题外话:个人快乐,不喜误喷,多谢支持
下面是一个很简单的通过createTrackbar来手动调试像素点的值来寻找图像中目标物体的代码
先介绍createTrackbar
int createTrackbar(const string& trackbarname, const string& winname, int* value, int count, TrackbarCallback onChange=0, void* userdata=0)
/*参数一:滑块的名字
*参数二:所要显示在的窗体的名字
*参数三:初始值阈值
*参数四:刻度范围
*参数五:回调函数
*/
下面是源码:
#include <opencv2/opencv.hpp>
#include <iostream>
//#include <cmath>
using namespace cv;
using namespace std;
int mo_value1 = 140;//选定显示像素点初始值b下限
int mo_value2 = 106;//选定显示像素点初始值g下限
int mo_value3 = 16;//选定显示像素点初始值r下限
int mo_moreb = 60;//选定显示像素点初始值b上限与下限差
int mo_moreg = 115;//选定显示像素点初始值g上限与下限差
int mo_morer = 85;//选定显示像素点初始值r上限与下限差
int mo_max = 255;//最大刻度
Mat src,dst,img;
RNG rng(12345);
char input[] = "阈值图";
void setthreshold1(int, void*);
int main()
{
try{
img = imread("/home/cxf1/img/test1.jpg");
if (img.empty()){
cout<< "kuai l "<<endl;
return -1;
}
namedWindow("img", WINDOW_AUTOSIZE);
namedWindow("阈值图", WINDOW_AUTOSIZE);
imshow("img", img);
// cvtColor(img, img, CV_BGR2GRAY); //转换图
createTrackbar("阈值B:", input, &mo_value1, mo_max, setthreshold1);
createTrackbar("阈值G:", input, &mo_value2, mo_max, setthreshold1);
createTrackbar("阈值R:", input, &mo_value3, mo_max, setthreshold1);
createTrackbar("阈值B上限与下限差:", input, &mo_moreb, mo_max, setthreshold1);
createTrackbar("阈值G上限与下限差:", input, &mo_moreg, mo_max, setthreshold1);
createTrackbar("阈值R上限与下限差:", input, &mo_morer, mo_max, setthreshold1);
setthreshold1(0, 0);
// imwrite("/home/cxf1/img/1-1.jpg",img);
waitKey(0);
return 0;
}catch(Exception e){
cout<<"over"<<endl;
return -1;
}
}
void setthreshold1(int, void*){
dst = img.clone();
src = img.clone();
// dst = Mat::zeros(img.size(), img.type());
for (int row=0; row<dst.rows; row++){
for (int col=0; col<dst.cols; col++){
if (dst.channels()==1){
int point_value = dst.at<uchar>(row, col);
if (point_value <mo_value1 || point_value>mo_value1+mo_moreb){
dst.at<uchar>(row, col) = 255;
}
}else if (dst.channels()==3){
int point_value1 = dst.at<Vec3b>(row, col)[0];
int point_value2 = dst.at<Vec3b>(row, col)[1];
int point_value3 = dst.at<Vec3b>(row, col)[2];
if (point_value1 <mo_value1 || point_value1>mo_value1+mo_moreb){
dst.at<Vec3b>(row, col)[0] = 255;
}
if (point_value2 <mo_value2 || point_value2>mo_value2+mo_moreg){
dst.at<Vec3b>(row, col)[1] = 255;
}
if (point_value3 <mo_value3 || point_value3>mo_value3+mo_morer){
dst.at<Vec3b>(row, col)[3] = 255;
}
if (point_value1 <mo_value1 || point_value1>mo_value1+mo_moreb ||
point_value2 <mo_value2 || point_value2>mo_value2+mo_moreg ||
point_value3 <mo_value3 || point_value3>mo_value3+mo_morer){
src.at<Vec3b>(row, col)[0] = 255;
src.at<Vec3b>(row, col)[1] = 255;
src.at<Vec3b>(row, col)[2] = 255;
}
}
}
}
imshow("阈值图", dst);
imshow("白块", src);
return ;
}
然后是给大家介绍一下这写代码的逻辑:
其实就是利用利用createTrackbar 去动态调整函数中的值,对于三通道的图分别设置其三个通道的像素点的值,而单通道使用b的设置值;
效果如下:
我们需要的是将左上角的两个颜色块像素值找到