如图,这次需要在图片中找到卷尺的红色刻度,所以需要对图像做过滤,只留下红色部分。
一开始的想法是分别找到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实现图像去除单一颜色背景
思路
因为背景是固定颜色,很容易筛选出背景,然后将其设为白色完全透明即可。
代码
#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越大,覆盖的像素越多)。
效果:
emmm,事实证明背景附近的颜色不是严格的背景色,后来将字填充后好多了。
以上这篇opencv之颜色过滤只留下图片中的红色区域操作就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]