『OpenCV3』色彩掩码

 本节我们实现这样一个算法,我们指定某种颜色和一个阈值,根据输入图片生成一张掩码,标记符合的像素。

源代码如下,我们使用一个class完成这个目标,其指定了两种构建函数,并通过逐像素扫描的形式生成掩码(process成员函数)。另外,本class做了仿函数处理(operator成员函数),类似于python中的__call__方法,可以直接调用实例像函数一样进行处理。

class ColorDetector {
private:
	int maxDist;  // 允许的最小差距
	cv::Vec3b target;  // 目标颜色
	cv::Mat result;  // 结果Mask图像

public:
	// 空构造函数
	ColorDetector() :maxDist(100), target(0, 0, 0) {};
	ColorDetector(uchar blue, uchar green, uchar red, int maxDist) : maxDist(maxDist) {
		setTargetColor(blue, green, red);
	};

	// 设置颜色差距阈值
	void setColorDistanceThreshold(int distance) {
		if (distance < 0)
			distance = 0;
		maxDist = distance;
	};
	// 获取颜色差距阈值
	int getColorDistanceThreshold() {
		return maxDist;
	};

	// 设置待检测颜色
	void setTargetColor(uchar blue, uchar green, uchar red) {
		target = cv::Vec3b(blue, green, red);
	};
	void setTargetColor(cv::Vec3b color) {
		target = color;
	};


	// 计算与目标颜色的差距
	int getDistanceToTargetColor(const cv::Vec3b& color) const {
		return getColorDistance(color, target);
	};
	// 计算两个颜色之间的距离
	int getColorDistance(const cv::Vec3b& color1, const cv::Vec3b& color2) const {
		return abs(color1[0] - color2[0]) +
			abs(color1[0] - color2[0]) +
			abs(color1[0] - color2[0]);
	};
	cv::Mat process(const cv::Mat &image);

	// operator()使类像函数一样工作
	cv::Mat operator()(const cv::Mat &image) {
		return process(image);
	};
};

cv::Mat ColorDetector::process(const cv::Mat &image) {
	// 为Mask结果申请空间
	result.create(image.size(), CV_8U);

	cv::Mat_<cv::Vec3b>::const_iterator it = image.begin<cv::Vec3b>();
	cv::Mat_<cv::Vec3b>::const_iterator itend = image.end<cv::Vec3b>();
	cv::Mat_<uchar>::iterator itout = result.begin<uchar>();

	for (; it != itend; ++it, ++itout) {
		if (getDistanceToTargetColor(*it) < maxDist) {
			*itout = 255;
		}
		else {
			*itout = 0;
		};
	};
	return result;
};

两种调用方法都列举了出来:

void code_3() {
    // 创建色彩检测器对象
    ColorDetector cdetect;
    cdetect.setTargetColor(10, 50, 10);
    // 读取图片
    cv::Mat image = cv::imread("test.jpg");
    // 处理图片
    cv::Mat result = cdetect.process(image);
    cv::imshow("色彩检测", result);

    // 仿函数
    ColorDetector colordetector(230, 190, 130, 100);
    result = colordetector(image);
    cv::imshow("仿函数色彩检测", result); };

输出图像展示:

猜你喜欢

转载自www.cnblogs.com/hellcat/p/9881492.html