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


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

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

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

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

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

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

    结果如图:

  • 相关阅读:
    Virtual Studio 2010在Release模式下进行调试的设置方法
    OpenGL Shader
    OGRE的安装编译
    开源GIS平台空间数据管理与发布技术研究
    风靡世界的小游戏2048源代码
    成为优秀程序员的几个阶段
    颜色空间模型(HSVLABRGBCMYK)
    希望自己的博客被知名搜索引擎收录的网址
    我的第一篇博客
    当你的善良受到委屈时
  • 原文地址:https://www.cnblogs.com/waw/p/5521696.html
Copyright © 2020-2023  润新知