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的另外几种语言实现
Jan 29 Python
详解Python的Django框架中的通用视图
May 04 Python
Python基于Flask框架配置依赖包信息的项目迁移部署
Mar 02 Python
查看TensorFlow checkpoint文件中的变量名和对应值方法
Jun 14 Python
对Python中创建进程的两种方式以及进程池详解
Jan 14 Python
基于PyQt4和PySide实现输入对话框效果
Feb 27 Python
python PyAutoGUI 模拟鼠标键盘操作和截屏功能
Aug 04 Python
centos7中安装python3.6.4的教程
Dec 11 Python
Python将二维列表list的数据输出(TXT,Excel)
Apr 23 Python
python如何求100以内的素数
May 27 Python
Python绘制组合图的示例
Sep 18 Python
Python使用plt.boxplot()函数绘制箱图、常用方法以及含义详解
Aug 14 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
盘点被央视点名过的日本动画电影 一部比一部强
2020/03/08 日漫
phpmyadmin操作流程
2006/10/09 PHP
php的sprintf函数的用法 控制浮点数格式
2014/02/14 PHP
php中实现精确设置session过期时间的方法
2014/07/17 PHP
PHP convert_uudecode()函数讲解
2019/02/14 PHP
PHP7数组的底层实现示例
2019/08/25 PHP
音乐播放用的的几个函数
2006/09/07 Javascript
javascript检查日期格式的函数[比较全]
2008/10/17 Javascript
JavaScript 浮点数运算 精度问题
2009/10/06 Javascript
用js脚本控制asp.net下treeview的NodeCheck的实现代码
2010/03/02 Javascript
jquery 简单的进度条实现代码
2010/03/11 Javascript
node.js中的fs.realpath方法使用说明
2014/12/16 Javascript
JS使用正则表达式实现关键字替换加粗功能示例
2016/08/03 Javascript
Jquery实现上下移动和排序代码
2016/10/17 Javascript
vue.js默认路由不加载linkActiveClass问题的解决方法
2017/12/11 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
Vue.js 表单控件操作小结
2018/03/29 Javascript
jQuery动态移除与增加onclick属性的方法详解
2018/06/07 jQuery
vue数组对象排序的实现代码
2018/06/20 Javascript
JavaScript折半查找(二分查找)算法原理与实现方法示例
2018/08/06 Javascript
微信小程序 MinUI组件库系列之badge徽章组件示例
2018/08/20 Javascript
Element-UI踩坑之Pagination组件的使用
2018/10/29 Javascript
详解vue开发中调用微信jssdk的问题
2019/04/16 Javascript
在Layui中操作数据表格,给指定单元格添加事件示例
2019/10/26 Javascript
基于JavaScript的数据结构队列动画实现示例解析
2020/08/06 Javascript
python中urlparse模块介绍与使用示例
2017/11/19 Python
Python使用combinations实现排列组合的方法
2018/11/13 Python
Python实现的爬取百度文库功能示例
2019/02/16 Python
python内存管理机制原理详解
2019/08/12 Python
在pycharm中配置Anaconda以及pip源配置详解
2019/09/09 Python
金融专业应届生求职信
2013/11/02 职场文书
小学生秋游活动方案
2014/02/23 职场文书
演讲稿开场白台词
2014/08/25 职场文书
群众路线查摆问题整改措施
2014/10/10 职场文书
python机器学习创建基于规则聊天机器人过程示例详解
2021/11/02 Python
Win11怎么解除儿童账号限制?Win11解除微软儿童账号限制方法
2022/07/07 数码科技