这次颜色识别使用C++来实现。颜色识别简单来说就是在 HSV 空间中找到符合颜色的阈值合适区域罢了。可以划分为以下几个步骤:
1、首先获取到图像
2、将获取到的图像颜色空间进行转换,转换为方便识别的 HSV 颜色模型
3、筛选阈值合适区域,作为识别的颜色
4、形态学滤波,对识别的区域进行滤波处理
5、提取被识别区域的轮廓,并标识出来
接下来实现一下吧!
这个实现主要是用来选择合适的阈值区间的。可以通过调节滑动栏的各个数值,查看颜色识别的效果。
#include
#include
using namespace std;
using namespace cv;
/* RED */
int iLowH = 156;
int iLowS = 43;
int iLowV = 46;
int iHighH = 180;
int iHighS = 255;
int iHighV = 255;
int main(int argc, char** argv)
{
system("color F0");
Mat hsvFrame;
Mat gaussImg;
Mat kernel;
Mat REDimg;
vector> REDcontours;
/* 1.获取视频源 */
VideoCapture camera(0);
if (!camera.isOpened())
{
cout << "打开摄像头失败,请确认摄像头是否安装成功" << endl;
return -1;
}
camera.set(CAP_PROP_FRAME_WIDTH, 1280);
camera.set(CAP_PROP_FRAME_HEIGHT, 720);
while (1)
{
Mat frame;
/* 2.获取视频帧 */
camera >> frame;
if (frame.empty())
{
cout << "没有获取到图像" << endl;
break;
}
/* 创建显示窗口和滑动条 */
namedWindow("Color");
createTrackbar("LowH", "Color", &iLowH, 179);
createTrackbar("LowS", "Color", &iLowS, 255);
createTrackbar("LowV", "Color", &iLowV, 255);
createTrackbar("HighH", "Color", &iHighH, 179);
createTrackbar("HighS", "Color", &iHighS, 255);
createTrackbar("HighV", "Color", &iHighV, 255);
/* 3.颜色空间转换 BGR 转 HSV */
cvtColor(frame, hsvFrame, COLOR_BGR2HSV);
/* 4.高斯滤波 */
GaussianBlur(hsvFrame, gaussImg, Size(5, 5), 0);
/* 5.筛选阈值合适区域 */
inRange(gaussImg, Scalar(iLowH, iLowS, iLowV),
Scalar(iHighH, iHighS, iHighV),
REDimg);
/* 6.形态学滤波 */
kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(REDimg, REDimg, MORPH_CLOSE, kernel);
morphologyEx(REDimg, REDimg, MORPH_OPEN, kernel);
/* 7.提取轮廓 */
findContours(REDimg, REDcontours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
/* 8.绘制轮廓图 */
drawContours(frame, REDcontours, -1, Scalar(0, 0, 255), 2);
imshow("video", frame);
if (27 == waitKey(1000 / 30))
break;
}
destroyAllWindows();
camera.release();
return 0;
}
这个实现用于识别R、G、B三原色。
#include
#include
using namespace std;
using namespace cv;
/*
* 颜色阈值
*/
int colorThreshold[][6] =
{
// {hmin, hmax, smin, smax, vmin, vmax}
{0, 10, 43, 255, 46, 255}, // RED
{156, 180, 43, 255, 46, 255}, // RED
{100, 124, 43, 255, 46, 255}, // GREEN
{35, 77, 150, 255, 200, 255}, // BULE
};
int main(int argc, char** argv)
{
system("color F0");
Mat hsvFrame;
Mat gaussImg;
Mat kernel;
Mat REDimg;
Mat GREENimg;
Mat BULEimg;
vector> REDcontours;
vector> GREENcontours;
vector> BLUEcontours;
/* 1.获取视频源 */
VideoCapture camera(0);
if (!camera.isOpened())
{
cout << "打开摄像头失败,请确认摄像头是否安装成功" << endl;
return -1;
}
camera.set(CAP_PROP_FRAME_WIDTH, 1280);
camera.set(CAP_PROP_FRAME_HEIGHT, 720);
while (1)
{
Mat frame;
/* 2.获取视频帧 */
camera >> frame;
if (frame.empty())
{
cout << "没有获取到图像" << endl;
break;
}
/* 3.颜色空间转换 BGR 转 HSV */
cvtColor(frame, hsvFrame, COLOR_BGR2HSV);
/* 4.高斯滤波 */
GaussianBlur(hsvFrame, gaussImg, Size(5, 5), 0);
/* 5.关键部分:筛选阈值合适区域 */
inRange(gaussImg,
Scalar(colorThreshold[0][0], colorThreshold[0][2], colorThreshold[0][4]),
Scalar(colorThreshold[0][1], colorThreshold[0][3], colorThreshold[0][5]),
REDimg);
inRange(gaussImg,
Scalar(colorThreshold[1][0], colorThreshold[1][2], colorThreshold[1][4]),
Scalar(colorThreshold[1][1], colorThreshold[1][3], colorThreshold[1][5]),
GREENimg);
inRange(gaussImg,
Scalar(colorThreshold[2][0], colorThreshold[2][2], colorThreshold[2][4]),
Scalar(colorThreshold[2][1], colorThreshold[2][3], colorThreshold[2][5]),
BULEimg);
/* 6.形态学滤波 */
kernel = getStructuringElement(MORPH_RECT, Size(3, 3));
morphologyEx(REDimg, REDimg, MORPH_CLOSE, kernel);
morphologyEx(REDimg, REDimg, MORPH_OPEN, kernel);
morphologyEx(GREENimg, GREENimg, MORPH_CLOSE, kernel);
morphologyEx(GREENimg, GREENimg, MORPH_OPEN, kernel);
morphologyEx(BULEimg, BULEimg, MORPH_CLOSE, kernel);
morphologyEx(BULEimg, BULEimg, MORPH_OPEN, kernel);
/* 7.提取轮廓 */
findContours(REDimg, REDcontours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
findContours(GREENimg, GREENcontours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
findContours(BULEimg, BLUEcontours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
/* 8.绘制轮廓图 */
drawContours(frame, REDcontours, -1, Scalar(0, 0, 255), 2);
drawContours(frame, GREENcontours, -1, Scalar(0, 255, 0), 2);
drawContours(frame, BLUEcontours, -1, Scalar(255, 0, 0), 2);
imshow("video", frame);
if (27 == waitKey(1000 / 30))
break;
}
destroyAllWindows();
camera.release();
return 0;
}