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中的__slots__缓存资源以节省内存开销的方法
Apr 02 Python
Python中使用hashlib模块处理算法的教程
Apr 28 Python
Python探索之Metaclass初步了解
Oct 28 Python
利用python库在局域网内传输文件的方法
Jun 04 Python
详解通过API管理或定制开发ECS实例
Sep 30 Python
Python实现的栈、队列、文件目录遍历操作示例
May 06 Python
python 自动轨迹绘制的实例代码
Jul 05 Python
Python 读取WAV音频文件 画频谱的实例
Mar 14 Python
Python通过socketserver处理多个链接
Mar 18 Python
Python脚本导出为exe程序的方法
Mar 25 Python
python函数调用,循环,列表复制实例
May 03 Python
Python如何获取文件指定行的内容
May 27 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实现生成透明背景的PNG缩略图函数分享
2014/07/08 PHP
PHP那些琐碎的知识点(整理)
2017/05/20 PHP
ThinkPHP+EasyUI之ComboTree中的会计科目树形菜单实现方法
2017/06/09 PHP
浅谈PHP接入(第三方登录)QQ登录 OAuth2.0 过程中遇到的坑
2017/10/13 PHP
JS实现仿京东淘宝竖排二级导航
2014/12/08 Javascript
js使用split函数按照多个字符对字符串进行分割的方法
2015/03/20 Javascript
jQuery事件绑定on()、bind()与delegate() 方法详解
2015/06/03 Javascript
jQuery根据用户电脑是mac还是pc加载对应样式的方法
2015/06/26 Javascript
jQuery实现高亮显示网页关键词的方法
2015/08/07 Javascript
jsTree使用记录实例
2016/12/01 Javascript
jQuery实现搜索页面关键字的功能
2017/02/16 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
JS返回顶部实例代码
2020/08/09 Javascript
vue组件生命周期详解
2017/11/07 Javascript
ionic3实战教程之随机布局瀑布流的实现方法
2017/12/28 Javascript
jQuery实现的两种简单弹窗效果示例
2018/04/18 jQuery
Vue 组件传值几种常用方法【总结】
2018/05/28 Javascript
JavaScript实现获取两个排序数组的中位数算法示例
2019/02/26 Javascript
JS自定义对象创建与简单使用方法示例
2020/01/15 Javascript
[47:48]DOTA2上海特级锦标赛D组小组赛#2 Liquid VS VP第三局
2016/02/28 DOTA
[01:14:31]Secret vs VG 2018国际邀请赛淘汰赛BO3 第一场 8.23
2018/08/24 DOTA
Python模块学习 datetime介绍
2012/08/27 Python
学习Python3 Dlib19.7进行人脸面部识别
2018/01/24 Python
python opencv实现运动检测
2018/07/10 Python
pycharm: 恢复(reset) 误删文件的方法
2018/10/22 Python
英国标准协会商店:BSI Shop
2019/02/25 全球购物
GOLFINO英国官网:高尔夫服装
2020/04/11 全球购物
保送生自荐信范文
2013/10/06 职场文书
汇源肾宝广告词
2014/03/20 职场文书
春节超市活动方案
2014/08/14 职场文书
学生会干部自我鉴定2014
2014/09/18 职场文书
聋哑人盗窃罪辩护词
2015/05/21 职场文书
党支部评议意见
2015/06/02 职场文书
2016年小学六一儿童节活动总结
2016/04/06 职场文书
Golang 正则匹配效率详解
2021/04/25 Golang
Zabbix对Kafka topic积压数据监控的解决方案
2022/07/07 Servers