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 专题六 局部变量、全局变量global、导入模块变量
Mar 20 Python
tornado 多进程模式解析
Jan 15 Python
django文档学习之applications使用详解
Jan 29 Python
Python 多维List创建的问题小结
Jan 18 Python
详解Python odoo中嵌入html简单的分页功能
May 29 Python
Python数据库小程序源代码
Sep 15 Python
如何基于python操作json文件获取内容
Dec 24 Python
Python unittest工作原理和使用过程解析
Feb 24 Python
解决jupyter notebook import error但是命令提示符import正常的问题
Apr 15 Python
Python gevent协程切换实现详解
Sep 14 Python
python 获取域名到期时间的方法步骤
Feb 10 Python
pygame面向对象的飞行小鸟实现(Flappy bird)
Apr 01 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
php后台程序与Javascript的两种交互方式
2009/10/25 PHP
WordPress网站性能优化指南
2015/11/18 PHP
php+js实现的无刷新下载文件功能示例
2019/08/23 PHP
Yii框架多语言站点配置方法分析【中文/英文切换站点】
2020/04/07 PHP
Javascript设置对象的ReadOnly属性(示例代码)
2013/12/25 Javascript
jQuery提示效果代码分享
2014/11/20 Javascript
JQuery创建DOM节点的方法
2015/06/11 Javascript
跟我学习javascript的prototype原型和原型链
2015/11/18 Javascript
Javascript 跨域知识详细介绍
2016/10/30 Javascript
Vue组件之Tooltip的示例代码
2017/10/18 Javascript
jQuery实现带右侧索引功能的通讯录示例【附源码下载】
2018/04/17 jQuery
Vue登录注册并保持登录状态的方法
2018/08/17 Javascript
axios取消请求的实践记录分享
2018/09/26 Javascript
JavaScript中import用法总结
2019/01/20 Javascript
JS面向对象编程基础篇(一) 对象和构造函数实例详解
2020/03/03 Javascript
JS Html转义和反转义(html编码和解码)的实现与使用方法总结
2020/03/10 Javascript
[32:47]完美世界DOTA2联赛 GXR vs IO 第二场 11.07
2020/11/09 DOTA
Python将阿拉伯数字转换为罗马数字的方法
2015/07/10 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
python 实现数组list 添加、修改、删除的方法
2018/04/04 Python
python使用tornado实现登录和登出
2018/07/28 Python
python获取依赖包和安装依赖包教程
2020/02/13 Python
Python实现爬取并分析电商评论
2020/06/19 Python
Python如何定义接口和抽象类
2020/07/28 Python
python的链表基础知识点
2020/09/13 Python
css3截图_动力节点Java学院整理
2017/07/11 HTML / CSS
Expedia瑞典官网:预订度假屋、酒店、汽车租赁、机票等
2021/01/23 全球购物
学生个人的自我评价分享
2013/11/05 职场文书
奥巴马演讲稿
2014/01/08 职场文书
护士辞职信模板
2014/01/20 职场文书
中秋晚会活动方案
2014/08/31 职场文书
网站出售协议书范文
2014/10/10 职场文书
2015年教师党员公开承诺书
2015/01/22 职场文书
超级实用的公文标题大全!
2019/07/19 职场文书
python数据可视化使用pyfinance分析证券收益示例详解
2021/11/20 Python
Linux下使用C语言代码搭建一个简单的HTTP服务器
2022/04/13 Servers