C++/OpenCV:同颜色检测提取

看到这个老哥写了一个类,但是没有demo,就使用这个类写了个例子

【OpenCV】OpenCV创建颜色识别类-class ColorDetector_Taily老段的专栏-CSDN博客

头文件 ColorDetector.h

#pragma once
#ifndef COLORDETECTOR_H_
#define COLORDETECTOR_H_

#include 
#include 
#include 

class ColorDetector {
private:
    int minDist;
    cv::Vec3b target;
    cv::Mat result;
    cv::Mat image;
    ColorDetector();
    static ColorDetector* singleton;

public:
    static ColorDetector* getInstance();
    static void destory();
    void setColorDistanceThreshold(int);
    int getColorDistanceThreshold() const;
    void setTargetColor(unsigned char, unsigned char, unsigned char);
    void setTargetColor(cv::Vec3b);
    cv::Vec3b getTargetColor() const;
    void process();
    int getDistance(const cv::Vec3b&) const;
    cv::Mat getResult() const;
    bool setInputImage(std::string);
    cv::Mat getInputImage() const;
};


#endif /* COLORDETECTOR_H_ */

 ColorDetector.cpp

#include "ColorDetector.h"

ColorDetector* ColorDetector::singleton = NULL;

ColorDetector::ColorDetector() :minDist(500) {
    target[0] = target[1] = target[2] = 0;
}

ColorDetector* ColorDetector::getInstance() {
    if (singleton == NULL) {
        singleton = new ColorDetector;
    }
    return singleton;
}

void ColorDetector::destory() {
    if (singleton != 0) {
        delete singleton;
    }
    singleton = 0;
}

void ColorDetector::setColorDistanceThreshold(int distance) {
    if (distance < 0) {
        distance = 0;
    }
    minDist = distance;
}

int ColorDetector::getColorDistanceThreshold() const {
    return minDist;
}

void ColorDetector::setTargetColor(unsigned char red,
    unsigned char green, unsigned char blue) {
    target[2] = red;
    target[1] = green;
    target[0] = blue;
}

void ColorDetector::setTargetColor(cv::Vec3b color) {
    target = color;
}

cv::Vec3b ColorDetector::getTargetColor() const {
    return target;
}

int ColorDetector::getDistance(const cv::Vec3b& color) const {
    return abs(color[0] - target[0]) + abs(color[1] - target[1]) + abs(color[2] - target[2]);
}

void ColorDetector::process() {
    result.create(image.rows, image.cols, CV_8U);
    cv::Mat_::const_iterator it = image.begin();
    cv::Mat_::const_iterator itend = image.end();
    cv::Mat_::iterator itout = result.begin();
    for (; it != itend; ++it, ++itout) {
        if (getDistance(*it) < minDist) {
            *itout = 255;
        }
        else {
            *itout = 0;
        }
    }
}

cv::Mat ColorDetector::getResult() const {
    return result;
}

bool ColorDetector::setInputImage(std::string filename) {
    image = cv::imread(filename);
    if (!image.data) {
        return false;
    }
    return true;
}

cv::Mat ColorDetector::getInputImage() const {
    return image;
}

就是给定一个颜色,然后判断图像中的颜色与给定颜色的误差:三个通道差值的和,然后二值化

下面是我使用这个类的例子:(类把构造函数私有化了)

#include 
#include
#include 
#include"ColorDetector.h"
using namespace cv;
using namespace std;

void onchange(int pos, void* data);
void onchange_r(int pos, void* data);
void onchange_g(int pos, void* data);
void onchange_b(int pos, void* data);
int main()
{
	ColorDetector* CD = ColorDetector::getInstance();
	CD->setInputImage("103.jpeg");
	//Mat img = CD->getInputImage();
	CD->setTargetColor(0, 0, 255);
	CD->setColorDistanceThreshold(10);
	CD->process();
	Mat out = CD->getResult();
	namedWindow("窗口", CV_WINDOW_NORMAL);
	resizeWindow("窗口", 600, 600);
	imshow("窗口", out);

	int tb_value = CD->getColorDistanceThreshold();
	Vec3b RGB_value = CD->getTargetColor();
	int R_value = (int)RGB_value[0];
	int G_value = (int)RGB_value[1];
	int B_value = (int)RGB_value[2];
	namedWindow("窗口1");
	resizeWindow("窗口1", 600, 300);
	createTrackbar("阈值", "窗口1", &tb_value, 1000, onchange,CD);
	createTrackbar("R", "窗口1", &R_value, 255, onchange_r, CD);
	createTrackbar("G", "窗口1", &G_value, 255, onchange_g, CD);
	createTrackbar("B", "窗口1", &B_value, 255, onchange_b, CD);
	waitKey();
	return 0;
}
void onchange(int pos, void* data)
{
	ColorDetector* CD = (ColorDetector*)data;
	CD->setColorDistanceThreshold(pos);
	CD->process();
	imshow("窗口", CD->getResult());
}
void onchange_r(int pos, void* data)
{
	ColorDetector* CD = (ColorDetector*)data;
	Vec3b RGB_value = CD->getTargetColor();
	RGB_value[2] = (uchar)pos;
	CD->setTargetColor(RGB_value);
	CD->process();
	imshow("窗口", CD->getResult());
}
void onchange_g(int pos, void* data)
{
	ColorDetector* CD = (ColorDetector*)data;
	Vec3b RGB_value = CD->getTargetColor();
	RGB_value[1] = (uchar)pos;
	CD->setTargetColor(RGB_value);
	CD->process();
	imshow("窗口", CD->getResult());
}
void onchange_b(int pos, void* data)
{
	ColorDetector* CD = (ColorDetector*)data;
	Vec3b RGB_value = CD->getTargetColor();
	RGB_value[0] = (uchar)pos;
	CD->setTargetColor(RGB_value);
	CD->process();
	imshow("窗口", CD->getResult());
}

测试图像如下:

C++/OpenCV:同颜色检测提取_第1张图片 

调节窗口如下: 

C++/OpenCV:同颜色检测提取_第2张图片

 当指定为红色时,会把图像中偏红的部分突出,如下:

C++/OpenCV:同颜色检测提取_第3张图片

 C++/OpenCV:同颜色检测提取_第4张图片

 C++/OpenCV:同颜色检测提取_第5张图片

效果还不错。 

你可能感兴趣的:(图像处理,C++,opencv,opencv)