看到这个老哥写了一个类,但是没有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());
}
测试图像如下:
调节窗口如下:
当指定为红色时,会把图像中偏红的部分突出,如下:
效果还不错。