直方圖定義:
直方圖均衡化-提高對比度-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);
輸出結果:
是不是可以用作二維碼識別?
失敗了,原因 模板圖像大小與源圖像上的定位點大小並不同。