OPenCV比较颜色

// 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();
}
  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值