直方图定义:
直方图均衡化-提高对比度-cv::equalizeHist
void equalizeHist( InputArray src, OutputArray dst ); //输入为八位灰度图像
从图片建立直方图-split,calcHist
api:
void split(const Mat& src, Mat* mvbegin);//三Mat图像转化为三个图像
void calcHist( const Mat* images, //输入图像
int nimages, //图像数目
const int* channels, //通道数
InputArray mask, //可选择图像中哪些像素参与直方图计算,不使用填noArray()
OutputArray hist, //输出直方图数据
int dims, //维数
const int* histSize, //直方图级数
const float** ranges, //值域范围
bool uniform = true, bool accumulate = false );
实战:
vector<Mat> bgr_plances;
split(src, bgr_plances);
int histSize = 256;
float range[] = { 0,256 };
const float *histRanges = { range };
Mat b_hist, g_hist, r_hist;
calcHist(&bgr_plances[0], 1, 0, noArray(), b_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_plances[1], 1, 0, noArray(), g_hist, 1, &histSize, &histRanges, true, false);
calcHist(&bgr_plances[2], 1, 0, noArray(), r_hist, 1, &histSize, &histRanges, true, false);
int hist_h = 400;
int hist_w = 512;
int bin_w = hist_w / histSize;
Mat histImage(hist_w, hist_h, CV_8UC3, Scalar(0, 0));
normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX, -1, noArray());
normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX, -1, noArray());
normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX, -1, noArray());
for (size_t i = 1; i < histSize; i++)
{
line(histImage, Point((i - 1)*bin_w, hist_h - int(b_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - int(b_hist.at<float>(i))), Scalar(255, 0, 0), 2, LINE_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - int(g_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - int(g_hist.at<float>(i))), Scalar(0, 255, 0), 2, LINE_AA);
line(histImage, Point((i - 1)*bin_w, hist_h - int(r_hist.at<float>(i - 1))),
Point((i)*bin_w, hist_h - int(r_hist.at<float>(i))), Scalar(0, 0, 255), 2, LINE_AA);
}
imshow("output", histImage);
直方图比较
对两个图像直方图求相关性,相关性高则可能是相同或相似的图片
double compareHist( const SparseMat& H1, const SparseMat& H2, int method );
//输入 输出 比较方法
CV_COMP_CORREL | 相关性方法 | 1 | |
CV_COMP_CHISQR_ALT | 卡方方法 | 1 | |
CV_COMP_INTERSECT | 交集法 | 1 | |
CV_COMP_BHATTACHARYYA | 巴氏距离 | 0 |
反向投影
暂时没看懂
模板匹配
源图像每个小块都与模板图像进行相关度计算,相关度最高的地方匹配
void matchTemplate( InputArray image, InputArray templ, //源图像与模板图像
OutputArray result, //输出结果,单通道32位浮点数,
//width=W-w+1,height=H-h+1
int method, //匹配方法
InputArray mask = noArray() );
匹配方法 | 输入 | 完全匹配 |
方差匹配 | TM_SQDIFF | 0 |
归一化方差匹配 | TM_SQDIFF_NORMED | 0 |
相关性匹配 | TM_CCORR | 很大的数 |
归一化的互相关匹配 | TM_CCORR_NORMED | 1 |
相关系数匹配 | TM_CCOEFF | 1(误匹配-1) |
归一化相关系数匹配 | TM_CCOEFF_NORMED | 1 |
尝试匹配二维码的三个定位点
int width = src.cols - temp.cols;
int height = src.rows - temp.rows;
Mat result(width, height, CV_32FC1);
matchTemplate(src, temp, result, CV_TM_SQDIFF_NORMED,Mat());
Point minLoc, maxLoc;
double min, max;
src.copyTo(dst);
for (size_t i = 0; i < 3; i++)
{
minMaxLoc(result, &min, &max, &minLoc, &maxLoc, Mat());
rectangle(dst, Rect(minLoc.x, minLoc.y, temp.cols, temp.rows), Scalar(0, 0, 255), 2, 8);
rectangle(result, Rect(minLoc.x, minLoc.y, temp.cols, temp.rows), Scalar(255, 255, 255), 8, 8);
}
imshow("result", result);
imshow("Output_Image", dst);
输出结果:
是不是可以用作二维码识别?
失败了,原因 模板图像大小与源图像上的定位点大小并不同。