目录
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;
}