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

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

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

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

[cpp] view plain copy

  1. IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );
  2. 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获取像素点的方式如下:

[cpp] view plain copy

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

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

[cpp] view plain copy

  1. CvScalar s;
  2. 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,也就是单通道

[cpp] view plain copy

  1. void colorFilter(CvMat *inputImage, CvMat *&outputImage)
  2. {
  3. int i, j;
  4. IplImage* image = cvCreateImage(cvGetSize(inputImage), 8, 3);
  5. cvGetImage(inputImage, image);
  6. IplImage* hsv = cvCreateImage( cvGetSize(image), 8, 3 );
  7. cvCvtColor(image,hsv,CV_BGR2HSV);
  8. int width = hsv->width;
  9. int height = hsv->height;
  10. for (i = 0; i < height; i++)
  11. for (j = 0; j < width; j++)
  12. {
  13. CvScalar s_hsv = cvGet2D(hsv, i, j);//获取像素点为(j, i)点的HSV的值
  14. /*
  15. opencv 的H范围是0~180,红色的H范围大概是(0~8)∪(160,180)
  16. S是饱和度,一般是大于一个值,S过低就是灰色(参考值S>80),
  17. V是亮度,过低就是黑色,过高就是白色(参考值220>V>50)。
  18. */
  19. CvScalar s;
  20. if (!(((s_hsv.val[0]>0)&&(s_hsv.val[0]<8)) || (s_hsv.val[0]>120)&&(s_hsv.val[0]<180)))
  21. {
  22. s.val[0] =0;
  23. s.val[1]=0;
  24. s.val[2]=0;
  25. cvSet2D(hsv, i ,j, s);
  26. }
  27. }
  28. outputImage = cvCreateMat( hsv->height, hsv->width, CV_8UC3 );
  29. cvConvert(hsv, outputImage);
  30. cvNamedWindow("filter");
  31. cvShowImage("filter", hsv);
  32. waitKey(0);
  33. cvReleaseImage(&hsv);
  34. }

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

结果如图:

时间: 2024-10-12 16:00:12

opencv之颜色过滤只留下图片中的红色区域的相关文章

laravel的filter()方法的使用 (方法使用给定的回调函数过滤集合的内容,只留下那些通过给定真实测试的内容)

filter 方法使用给定的回调函数过滤集合的内容,只留下那些通过给定真实测试的内容: $collection = collect([1, 2, 3, 4]); $filtered = $collection->filter(function ($value, $key) { return $value > 2; }); $filtered->all(); // [3, 4] 實例代碼: //商家 $business= Business::Status(1)->get(); //帥

WIN10下设置惠普HP1050等打印机打印颜色,只打黑白或彩色

今天同事问了一个问题,如何在WIN10下,设置惠普打印机只打印黑白, 上网搜了下,没有找到任何信息,只有在WIN8前系统设置的内容,经过几番折腾,得出此文. WIN10下设置惠普HP1050等打印机打印颜色,只打黑白或彩色,步骤如下: 1.右键 打印机,选择打印机首选项 2.高级  --  以灰度打印 3.点击  关,关则为彩色打印,选择 仅黑色墨水 即为黑白打印.

OpenCV——基于颜色的物体检测系统

这次区别于证件照,我试着编写了一下在复杂背景下分离纯色物体的系统,因为只是简单的编程,所以结果有待优化,先分析一下实验环境: 这次的背景杂乱,虽然主体是粉色主导,但是因为光照不统一,色域跨度较大,倒影中也有粉色痕迹,杯壁上有花纹,这种情况下边缘检测误差很大. 为了让计算机更好的识别主体颜色,要先将RGB色域转换为HSV色域,在HSV色域中,红色的H值在(0,3)U(156,180)中.粉色的S值饱和度不高,但是比白色要高很多,区间在(50,150)以内. V代表Value,只有黑色或偏黑的颜色V

OpenCV——视频颜色识别

#include <opencv2/opencv.hpp> #include <iostream> using namespace std; using namespace cv; int minh,maxh,mins,maxs,minv,maxv; void helptext() { cout << "B——黑色\n"; cout << "H——灰色\n"; cout << "W——白色\n&q

OpenCV默认颜色通道

网上查了一下,OpenCV读取图片之后Mat默认的颜色通道都说是BGR,有点不信,试了一下,先用PS做一张纯色的图片,还有颜色的RGB值       然后用OpenCV读取图片之后读取RGB值逐一显示出来: 1 // OpenCV_default_color_channel.cpp : 定义控制台应用程序的入口点. 2 // 3 4 5 #include "opencv2/core/core.hpp" 6 #include "opencv2/highgui/highgui.h

adb进阶知识,如何过滤只查看某一个app的日志

前面大概学习了adb基础,但是adb的存在,在测试人员中究竟有什么必要,以及看log时,那么多的log,让我们看个屁啊,所以这一次,我决定一定要把adb这件事情搞清楚. 1.先来看最感兴趣的adb日志 首先来了解一共概念,安卓的日志有那些: Android 系统的日志分为两部分,底层的 Linux 内核日志输出到 /proc/kmsg,Android 的日志输出到 /dev/log.一般我们说的adb logcat看的都是android的日志 使用adb shell dmesg 可以能看Andr

数据库删除数据表重复数据,只留下ID较小的行

删除表中重复数据,留下ID比较小的行 delete from 表 where [重复字段] in (select [重复字段] from 表 group by 字段 having count([字段]) > 1) and ID not in (select min(ID) from [表] group by [字段] having count([字段])> 1)

c# 正则表达式 匹配中括号&amp;颜色过滤

现在需要匹配 [color=#000000],以"[color"开头,以"]"结束,中间字符数量不限制,最后返回所有匹配的下标. 代码如下: 1 /// <summary> 2 /// 取得所有匹配项的下标 3 /// </summary> 4 /// <param name="source">原内容</param> 5 /// <returns>返回匹配列表的下标</return

ColorMatrixColorFilter颜色过滤(离线用户的灰色头像处理)

Android的图片资源默认是静态的,单实例:如果两个IM好友的头像一样,最简单的都是用的软件自带头像,有一个在线,一个离线,直接改变头像的灰度,则两个用户的头像都会变灰或者在线,答案是:Drawable.mutate(). Drawable mDrawable = context.getResources().getDrawable(R.drawable.face_icon); //Make this drawable mutable. //A mutable drawable is guar