// opencvcolor.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
#include <iostream>
#include <opencv2/highgui.hpp>
#include <opencv2\imgproc.hpp>
#include <opencv2\core.hpp>
using namespace std;
using namespace cv;
/*
任务要求:
读入一幅彩色图像,并选定图像中某像素颜色为待检测目标色,
检测颜色与该目标色接近的所有像素并在结果图中将这些像素设为白色,其他像素设为黑色,
显示原始图、待检测颜色(构造一幅图像,将其所有颜色设为待检测颜色)以及检测结果。
*/
class ColorDetector {
private:
int maxDist; // 允许的最大颜色差距
cv::Vec3b target; // 目标颜色
// 计算两个颜色之间的距离
int getColorDistance(const cv::Vec3b& color1,
const cv::Vec3b& color2) const {
// 计算城区距离
return abs(color1[0] - color2[0]) +
abs(color1[1] - color2[1]) +
abs(color1[2] - color2[2]);
}
// 计算与目标颜色的差距
int getDistanceToTargetColor(const cv::Vec3b& color) const {
return getColorDistance(color, target);
}
public:
// 空构造函数,在此初始化默认参数
ColorDetector() : maxDist(100), target(0, 0, 0) {}
// 从输入图像image中检测与target颜色相近的像素,在结果图中用白色表示
// 其他颜色像素在结果图中用黑色表示
cv::Mat process(const cv::Mat& image) {
cv::Mat result;
// 重新分配二值结果图像
// 与输入图像的尺寸相同,不过是单通道
result.create(image.size(), CV_8U);
// 遍历图像,处理每个像素
for (int j = 0; j < image.rows; j++) {
// 取得行j的首地址
const cv::Vec3b* input = image.ptr<cv::Vec3b>(j);
uchar* output = result.ptr<uchar>(j);
// 遍历该行的每一个像素
for (int i = 0; i < image.cols; i++) {
// 比较与目标颜色的差距
if (getDistanceToTargetColor(input[i]) <= maxDist)
output[i] = 255;
else
output[i] = 0;
}
}
return result;
}
// 设置颜色差距的阈值
// 阈值必须是正数,否则就置为0
void setColorDistanceThreshold(int distance) {
if (distance < 0)
distance = 0;
maxDist = distance;
}
// 取得颜色差距的阈值
int getColorDistanceThreshold() const {
return maxDist;
}
// 设置需要检测的颜色
void setTargetColor(uchar blue, uchar green, uchar red) {
// 次序为BGR
target = cv::Vec3b(blue, green, red);
}
// 设置需要检测的颜色
void setTargetColor(cv::Vec3b color) {
target = color;
}
// 获取需要检测的颜色
cv::Vec3b getTargetColor() const {
return target;
}
};
void compare_color(int event, int x, int y, int flags, void* userdata)
{
// 1. 创建图像处理器对象
ColorDetector cdetect;
// 2.读取输入的图像
Mat image = (*((Mat*)userdata)).clone();
if (event == EVENT_LBUTTONDOWN)
{
Scalar color = image.at<Vec3b>(x, y);
// 3. 设置输入参数
cdetect.setTargetColor(color[0], color[1], color[2]);// 这里表示天空颜色
cdetect.setColorDistanceThreshold(100); // 设置阈值
// 4. 处理图像并显示结果
cv::imshow("Result", cdetect.process(image));
}
}
void main()
{
Mat image;
image = imread("p.jpg");
imshow("Image", image);
if (image.empty())
{
cout << "读取图像失败" << endl;
exit(EXIT_FAILURE);
}
cout << "请点击图片进行选区。" << endl;
setMouseCallback("Image", compare_color, (void*)(&image));
int c = waitKey(0);
if (c = 27)
{
exit;
}
destroyAllWindows();
}
OPenCV比较颜色
最新推荐文章于 2023-10-09 11:00:49 发布