#include<opencv2/highgui.hpp>
#include<opencv2/core.hpp>
#include<opencv2/opencv.hpp>
//threshold 代表一个阈值
//当红色像素数少于这个阈值时,返回true
//当红色像素数超过这个阈值时,返回false
bool colorFilter(cv::Mat &inputImage,int threshold)
{
cv::Mat hsv;
cv::cvtColor(inputImage, hsv, CV_BGR2HSV);
//用来记录图像中红色像素的数目,初始化为图像像素总数,
int pixel_size = hsv.rows*hsv.cols;
for (int i = 0; i < hsv.rows; ++i)
{
for (int j = 0; j < hsv.cols; ++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 (!((hsv.at<cv::Vec3b>(i,j)[0]> 0 && hsv.at<cv::Vec3b>(i, j)[0] < 8) || (hsv.at<cv::Vec3b>(i, j)[0] > 160&& hsv.at<cv::Vec3b>(i,j)[0] < 180)))
{
hsv.at<cv::Vec3b>(i, j)[0] = 0;
hsv.at<cv::Vec3b>(i, j)[1] = 0;
hsv.at<cv::Vec3b>(i, j)[2] = 0;
--pixel_size;
}
}
}
cv::Mat rgb;
cv::cvtColor(hsv, rgb, CV_HSV2BGR);
cv::imwrite("aft_11.jpg",rgb);
cv::namedWindow("aft_segmentation");
cv::imshow("aft_segmentation", rgb);
cv::waitKey(3);
std::cout << "红色像素数:" <<pixel_size<<std::endl;
if (pixel_size < threshold)
return true;
else
return false;
}
opencv坐标系:
注意:
-
坐标体系中的零点坐标为图片的左上角,X轴为图像矩形的上面那条水平线;Y轴为图像矩形左边的那条垂直线。该坐标体系在诸如结构体Mat,Rect,Point中都是适用的。
-
在使用image.at(x1, x2)来访问图像中点的值的时候,x1并不是图片中对应点的x轴坐标,而是图片中对应点的y坐标。因此其访问的结果其实是访问image图像中的Point(x2, x1)点,即与image.at(Point(x2, x1))效果相同。
-
注意at()函数是用模板完成的。使用方法为:image.at<Vec3b>(row,col)[i], i表示通道的序号。
-
对于单通道图像,其元素类型一般为 8U (即 8位无符号整数),当然也可以 是 16S 、32F32F 等;这些类型可以直接用 uchar 、short 、float等 C/C++语言中的基本数据类型表达。
-
如果多通道图像,如RGB彩色图像,需要用三个通道来表示。在这种情况 下,如果依然将图像视作一个二维矩阵那么矩阵的元素不再是基本数据类型。
-
参考资料:
https://blog.youkuaiyun.com/liumoude6/article/details/78318053?locationNum=10&fps=1