opencv之颜色过滤只留下图片中的红色区域操作


Posted in Python onJune 05, 2020

如图,这次需要在图片中找到卷尺的红色刻度,所以需要对图像做过滤,只留下红色部分。

opencv之颜色过滤只留下图片中的红色区域操作

一开始的想法是分别找到RGB值,然后找到红色区域的部分保留就可以了,不过好像很难确定红色区域的RGB取值范围,所以要把图片转化到HSV空间中去。

在opencv中直接使用cvCvtColor函数就可以啦。

IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );

cvCvtColor(image,hsv,CV_BGR2HSV);

opencv 的H范围是0~180,红色的H范围大概是(0~8)∪(160,180) ,S是饱和度,一般是大于一个值,S过低就是灰色(参考值S>80),V是亮度,过低就是黑色,过高就是白色(参考值220>V>50)。

所以接下来要做的就是遍历图像,获取图像每个像素点的H,S,V分量,然后做判断,满足条件的就保留,不满足的就赋值为黑色。

我是用opencv中的IplImage来存储图片的。

IplImage获取像素点的方式如下:

CvScalar s_hsv = cvGet2D(hsv, j, i);//获取像素点为(i, j)点的HSV的值,i是width值,j是height值

IplImage对像素点赋值的方式如下:

CvScalar s;

cvSet2D(hsv, j ,i, s);//对(i,j)处的像素点赋值

分别取得H,S,V分量,注意图像转化的时候BGR2HSV,所以s.val[0]是B或H的值,s.val[1]是G或S的值,s.val[2]则是R或V的值。

因为师弟喜欢用CvMat,所以输入都改成了CvMat,使用的时候inputImage是希望过滤的图片,outputImage则为输出图片,因为outputImage会在函数中进行空间申请与赋值,所以传入参数的时候直接把它设成NULL就可以了。

另外要注意一点,因为是对彩色图像做实验,所以如果传入的图片不是3通道的彩色图片,那么就会出内存错误。

以下打开图片或创建图片的方式都是单通道方式,会出现内存错误。

IplImage *input = cvLoadImage(path, 0),
CvMat* M = cvCreateMat(4,4,CV_32FC1); //或是8UC1, 因为C1表示nChannel = 1,也就是单通道

void colorFilter(CvMat *inputImage, CvMat *&outputImage)
{
 int i, j;
 IplImage* image = cvCreateImage(cvGetSize(inputImage), 8, 3);
 cvGetImage(inputImage, image); 
 IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 ); 
 
 cvCvtColor(image,hsv,CV_BGR2HSV);
 int width = hsv->width;
 int height = hsv->height;
 for (i = 0; i < height; i++)
 for (j = 0; j < width; j++)
 {
 CvScalar s_hsv = cvGet2D(hsv, i, j);//获取像素点为(j, i)点的HSV的值 
 /*
 opencv 的H范围是0~180,红色的H范围大概是(0~8)∪(160,180) 
 S是饱和度,一般是大于一个值,S过低就是灰色(参考值S>80),
 V是亮度,过低就是黑色,过高就是白色(参考值220>V>50)。
 */
 CvScalar s;
 if (!(((s_hsv.val[0]>0)&&(s_hsv.val[0]<8)) || (s_hsv.val[0]>120)&&(s_hsv.val[0]<180)))
 {
 s.val[0] =0;
 s.val[1]=0;
 s.val[2]=0;
 cvSet2D(hsv, i ,j, s);
 }
 
 }
 outputImage = cvCreateMat( hsv->height, hsv->width, CV_8UC3 );
 cvConvert(hsv, outputImage);
 cvNamedWindow("filter");
 cvShowImage("filter", hsv);
 waitKey(0);
 cvReleaseImage(&hsv);
}

关于函数还有一点要说明,H分量我取得是(0,8),(120,180),S与V分量没有做筛选,如果按照注释部分的进行筛选结果不是很好。

结果如图:

opencv之颜色过滤只留下图片中的红色区域操作

补充知识:opencv实现图像去除单一颜色背景

思路

opencv之颜色过滤只留下图片中的红色区域操作

因为背景是固定颜色,很容易筛选出背景,然后将其设为白色完全透明即可。

代码

#coding=utf-8
import cv2 as cv
bg_color = [197, 102, 6]
threshold = 3000

def calc_diff(pixel):
'''
计算pixel与背景的离差平方和,作为当前像素点与背景相似程度的度量
'''
  return (pixel[0]-bg_color[0])**2 + (pixel[1]-bg_color[1])**2 + (pixel[2]-bg_color[2])**2

def remove_bg():
  image_path = './logo.png'
  logo = cv.imread(image_path)
  logo = cv.cvtColor(logo, cv.COLOR_BGR2BGRA) #将图像转成带透明通道的BGRA格式
  h, w = logo.shape[0:2]
  for i in range(h):
    for j in range(w):
      if calc_diff(logo[i][j]) < threshold:
      #若果logo[i][j]为背景,将其颜色设为白色,且完全透明
        logo[i][j][0] = 255
        logo[i][j][1] = 255
        logo[i][j][2] = 255
        logo[i][j][3] = 0
 
  cv.imwrite("./logo_rmbg.png", logo)
        
if __name__ == '__main__':
  remove_bg()

使用方法

修改第5行的bg_color为图片背景的bgr值,以及第6行的threshold(threshold越大,覆盖的像素越多)。

效果:

opencv之颜色过滤只留下图片中的红色区域操作

emmm,事实证明背景附近的颜色不是严格的背景色,后来将字填充后好多了。

opencv之颜色过滤只留下图片中的红色区域操作

以上这篇opencv之颜色过滤只留下图片中的红色区域操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持三水点靠木。

Python 相关文章推荐
python 布尔操作实现代码
Mar 23 Python
Python实现去除代码前行号的方法
Mar 10 Python
python将图片文件转换成base64编码的方法
Mar 14 Python
详解Python编程中time模块的使用
Nov 20 Python
python嵌套函数使用外部函数变量的方法(Python2和Python3)
Jan 31 Python
python if not in 多条件判断代码
Sep 21 Python
python 移除字符串尾部的数字方法
Jul 17 Python
python2与python3共存问题的解决方法
Sep 18 Python
Python2和Python3的共存和切换使用
Apr 12 Python
使用Python做定时任务及时了解互联网动态
May 15 Python
Python Web框架之Django框架cookie和session用法分析
Aug 16 Python
在终端启动Python时报错的解决方案
Nov 20 Python
Python参数传递及收集机制原理解析
Jun 05 #Python
python如何进行矩阵运算
Jun 05 #Python
Opencv求取连通区域重心实例
Jun 04 #Python
Python中zip函数如何使用
Jun 04 #Python
Python中有几个关键字
Jun 04 #Python
Python如何转换字符串大小写
Jun 04 #Python
如何在Python对Excel进行读取
Jun 04 #Python
You might like
多文件上传的例子
2006/10/09 PHP
php adodb分页实现代码
2009/03/19 PHP
解决php接收shell返回的结果中文乱码问题
2014/01/23 PHP
php模板引擎技术简单实现
2016/03/15 PHP
php+mysql实现的二级联动菜单效果详解
2016/05/10 PHP
详解PHP用substr函数截取字符串中的某部分
2016/12/03 PHP
js实现数组去重、判断数组以及对象中的内容是否相同
2013/11/29 Javascript
window.print打印指定div指定网页指定区域的方法
2014/08/04 Javascript
jQuery Mobile开发中日期插件Mobiscroll使用说明
2016/03/02 Javascript
不能不知道的10个angularjs英文学习网站
2016/03/23 Javascript
深入理解JS中的substr和substring
2016/04/26 Javascript
JavaScript对Json的增删改属性详解
2016/06/02 Javascript
jQuery 检查某个元素在页面上是否存在实例代码
2016/10/27 Javascript
Bootstrap中glyphicons-halflings-regular.woff字体报404错notfound的解决方法
2017/01/19 Javascript
微信小程序商城项目之侧栏分类效果(1)
2017/04/17 Javascript
基于javascript中的typeof和类型判断(详解)
2017/10/27 Javascript
vue中使用ueditor富文本编辑器
2018/02/08 Javascript
vue实例中data使用return包裹的方法
2018/08/27 Javascript
ES6中Symbol、Set和Map用法详解
2019/08/20 Javascript
JavaScript或jQuery 获取option value值方法解析
2020/05/12 jQuery
Python中处理字符串之isalpha()方法的使用
2015/05/18 Python
python判断一个集合是否包含了另外一个集合中所有项的方法
2015/06/30 Python
深入理解Python变量与常量
2016/06/02 Python
python学习教程之使用py2exe打包
2017/09/24 Python
Python工厂函数用法实例分析
2018/05/14 Python
Python面向对象类编写细节分析【类,方法,继承,超类,接口等】
2019/01/05 Python
django 实现编写控制登录和访问权限控制的中间件方法
2019/01/15 Python
Python中的相关分析correlation analysis的实现
2019/08/29 Python
python pygame实现滚动横版射击游戏城市之战
2019/11/25 Python
Fresh馥蕾诗英国官网:法国LVMH集团旗下高端天然护肤品牌
2018/11/01 全球购物
竞聘医务工作人员的自我评价分享
2013/11/04 职场文书
董事长秘书工作总结
2015/08/14 职场文书
关于公司年会的开幕词
2016/03/04 职场文书
个人房屋租赁合同(标准范本)
2019/09/16 职场文书
python批量更改目录名/文件名的方法
2021/04/18 Python
Mysql binlog日志文件过大的解决
2021/10/05 MySQL