目录
1、图像直方图
1.1 直方图统计
1.2 直方图像素统计
1.3 直方图绘制
2、直方图均衡化
2.1 实现
2.2 效果
3、直方图匹配
3.1 匹配原理
3.2 实现
4、模板匹配
4.1 模板匹配
4.2 模板匹配函数
4.3 模板匹配方法标志
4.4 代码实现
1、图像直方图
1.1 直方图统计
1.2 直方图像素统计
1.3 直方图绘制
//直方图绘制
int test1()
{
Mat img = imread("F:/testMap/lena.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat gray;
cvtColor(img, gray, COLOR_BGR2GRAY);//设置提取直方图的相关变量
Mat hist; //用于存放直方图计算结果
const int channels[1] = { 0 };//通道索引
const int bins[1] = { 256 }; //直方图的维度,其实就是像素灰度值的最大值
float inRanges[2] = { 0, 255 };
const float* ranges[1] = { inRanges }; //像素灰度值范围
calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges);//计算图像直方图
//准备绘制直方图
int hist_w = 512;
int hist_h = 400;
int width = 2;
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
//for (int i = 1; i <= hist.rows; i++)
//{
// rectangle(histImage, Point(width*(i - 1), hist_h - 1),
// Point(width*i - 1, hist_h - cvRound(hist.at<float>(i - 1) / 15)),
// Scalar(255, 255, 255), -1);
//}
Mat hist_INF;
normalize(hist, hist_INF, 1, 0, NORM_INF, -1, Mat());//归一化
for (int i = 1; i <= hist_INF.rows; i++)
{
rectangle(histImage, Point(width*(i - 1), hist_h - 1),
Point(width*i - 1, hist_h - cvRound(hist_h*hist_INF.at<float>(i - 1)) - 1), Scalar(255, 255, 255), -1);
}
imshow("histImage", histImage);
imshow("gray", gray);
waitKey(0);
}
2、直方图均衡化
2.1 实现
//直方图均衡化
void drawHist(Mat &hist, int type, string name)//归一化并绘制直方图函数
{
int hist_w = 512;
int hist_h = 512;
int width = 2;
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
normalize(hist, hist, 1, 0, type, -1, Mat());
for (int i = 1; i <= hist.rows; i++)
{
rectangle(histImage, Point(width*(i - 1), hist_h - 1),
Point(width*i - 1, hist_h - cvRound(hist_h*hist.at<float>(i - 1)) - 1),
Scalar(255, 255, 255), -1);
}
imshow(name, histImage);
}
int test2()
{
Mat img = imread("F:/testMap/hist.png");
if (img.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat gray, hist, hist2;
cvtColor(img, gray, COLOR_BGR2GRAY);
Mat equalImg;
equalizeHist(gray, equalImg); //将图像直方图均衡化
const int channels[1] = { 0 };
float inRanges[2] = { 0, 255 };
const float* ranges[1] = { inRanges };
const int bins[1] = { 256 };
calcHist(&gray, 1, channels, Mat(), hist, 1, bins, ranges);
calcHist(&equalImg, 1, channels, Mat(), hist2, 1, bins, ranges);
drawHist(hist, NORM_INF, "hist");
drawHist(hist2, NORM_INF, "hist2");
imshow("原图", gray);
imshow("均衡化后的图像", equalImg);
}
2.2 效果
显示更加清晰的纹理信息
3、直方图匹配
3.1 匹配原理
3.2 实现
void drawHist(Mat &hist, int type, string name)//归一化并绘制直方图函数
{
int hist_w = 512;
int hist_h = 512;
int width = 2;
Mat histImage = Mat::zeros(hist_h, hist_w, CV_8UC3);
normalize(hist, hist, 1, 0, type, -1, Mat());
for (int i = 1; i <= hist.rows; i++)
{
rectangle(histImage, Point(width*(i - 1), hist_h - 1),
Point(width*i - 1, hist_h - cvRound(20*hist_h*hist.at<float>(i - 1)) - 1),//20* 改变直方图的高度
Scalar(255, 255, 255), -1);
}
imshow(name, histImage);
}
//直方图匹配
int test3()
{
Mat img1 = imread("F:/testMap/hist.png");
Mat img2 = imread("F:/testMap/lena.png");
if (img1.empty() || img2.empty())
{
cout << "请确认图像文件名称是否正确" << endl;
return -1;
}
Mat hist1, hist2;
//计算两张图像直方图
const int channels[1] = { 0 };
float inRanges[2] = { 0, 255 };
const float* ranges[1] = { inRanges };
const int bins[1] = { 256 };
calcHist(&img1, 1, channels, Mat(), hist1, 1, bins, ranges);
calcHist(&img2, 1, channels, Mat(), hist2, 1, bins, ranges);
//归一化两张图像的直方图
drawHist(hist1, NORM_L1, "hist1");
drawHist(hist2, NORM_L1, "hist2");
//计算两张图像直方图的累积概率
float histl_cdf[256] = { hist1.at<float>(0) };
float hist2_cdf[256] = { hist2.at<float>(0) };
for (int i = 1; i < 256; i++)
{
histl_cdf[i] = histl_cdf[i - 1] + hist1.at<float>(i);
hist2_cdf[i] = hist2_cdf[i - 1] + hist2.at<float>(i);
}
//构建累积概率误差矩阵
float diff_cdf[256][256];
for (int i = 0; i < 256; i++)
{
for (int j = 0; j < 256; j++)
{
diff_cdf[i][j] = fabs(histl_cdf[i] - hist2_cdf[j]);
}
}
//生成LUT映射表
Mat lut(1, 256, CV_8U);
for (int i = 0; i < 256; i++)
{
//查找源灰度级为i的映射灰度
//和i的累积概率差值最小的规定化灰度
float min = diff_cdf[i][0];
int index = 0;
//寻找累积概率误差矩阵中每一行中的最小值
for (int j = 1; j < 256; j++)
{
if (min > diff_cdf[i][j])
{
min = diff_cdf[i][j];
index = j;
}
lut.at<uchar>(i) = (uchar)index;
}
}
Mat result,hist3;
LUT(img1,lut,result);
imshow("待匹配图像",img1);
imshow("匹配的模板图像",img2);
imshow("直方图匹配结果", result);
calcHist(&result,1,channels, Mat(), hist3,1, bins,ranges);
drawHist(hist3,NORM_L1,"hist3");//绘制匹配后的图像直方图
waitKey(0);
return 0;
}
4、模板匹配
4.1 模板匹配
4.2 模板匹配函数
4.3 模板匹配方法标志
0 1标志匹配结果越大说明越不匹配
4.4 代码实现
//模板匹配
int test4()
{
Mat img = imread("F:/testMap/lena.png");
Mat temp = imread("F:/testMap/lenaFace.png");
Mat result;
matchTemplate(img,temp,result,TM_CCOEFF_NORMED);
double maxVal,minVal;
Point maxLoc,minLoc;
minMaxLoc(result, &minVal, &maxVal, &minLoc, &maxLoc);
rectangle(img,Point(maxLoc.x,maxLoc.y),Point(maxLoc.x + temp.cols,maxLoc.y + temp.rows),Scalar(0,0,255),2);
imshow("原图像", img);
imshow("模板", temp);
imshow("result", result);
waitKey(0);
return 0;
}