图像直方图
void QuickDemo::histogram_demo(Mat& img)
{
//进行三通道的分离
std::vector<Mat> bgr_plane;
split(img,bgr_plane);
//定义预备用的参数
const int channel[1] = { 0 };
const int bins[1] = { 256 };
float Range[2] = { 0,255 };
const float* histRange = { Range };
Mat b_hist, g_hist, r_hist;
int num_bins = 256;
calcHist(&bgr_plane[0],1,0,Mat(),b_hist,1,&num_bins,&histRange);
calcHist(&bgr_plane[1], 1, 0, Mat(), g_hist, 1, &num_bins, &histRange);
calcHist(&bgr_plane[2], 1, 0, Mat(), r_hist, 1, &num_bins, &histRange);
//以上是样例
int hist_h = 512;
int hist_w = 400;
Mat hist_Image = Mat::zeros(Size(hist_h, hist_w), CV_8UC3);
//归一化直方图图像
normalize(b_hist, b_hist, 0, hist_h, NORM_MINMAX,-1,Mat());
normalize(g_hist, g_hist, 0, hist_h, NORM_MINMAX,-1, Mat());
normalize(r_hist, r_hist, 0, hist_h, NORM_MINMAX,-1, Mat());
int binStep = cvRound((float)hist_w / (float)num_bins); //通过将宽度除以区间数来计算binStep变量
for (int i = 1; i < num_bins; i++)
{
line(hist_Image,
Point(binStep * (i - 1), hist_h - cvRound(b_hist.at<float>(i - 1))),
Point(binStep * (i), hist_h - cvRound(b_hist.at<float>(i))),
Scalar(255, 0, 0)
);
line(hist_Image,
Point(binStep * (i - 1), hist_h - cvRound(g_hist.at<float>(i - 1))),
Point(binStep * (i), hist_h - cvRound(g_hist.at<float>(i))),
Scalar(0, 255, 0)
);
line(hist_Image,
Point(binStep * (i - 1), hist_h - cvRound(r_hist.at<float>(i - 1))),
Point(binStep * (i), hist_h - cvRound(r_hist.at<float>(i))),
Scalar(0, 0, 255)
);
}
Mat dst = hist_Image;
imshow("dst", dst);
}
二维直方图
基于HSV图像进行编写
void QuickDemo::histogram_2d_demo(Mat& img)
{
//生成2D直方图
Mat hsv, hs_hist;
cvtColor(img, hsv, COLOR_BGR2HSV);
int hbins = 30, sbins = 32;//这是在hs两个维度上的显示间隔
int hist_bins[] = { hbins,sbins };
float h_range[] = {0,180};
float s_range[] = {0,255};
const float* hs_range[]= { h_range,s_range };
int hs_channel[] = { 0,1 };
calcHist(&hsv, 1, hs_channel, Mat(), hs_hist, 2, hist_bins, hs_range, true, false);
double maxVal = 0;
minMaxLoc(hs_hist, 0, &maxVal, 0, 0);
int scale = 10;
Mat hist2d_image = Mat::zeros(sbins * scale, hbins * scale, CV_8UC3);
for (int h = 0; h < hbins; h++)
{
for (int s = 0; s < sbins; s++)
{
float bindVal = hs_hist.at<float>(h, s);
int intensity = cvRound(bindVal*255/maxVal);
rectangle(hist2d_image, Point(h * scale, s * scale),
Point((h + 1) * scale - 1, (s + 1) * scale-1),
Scalar::all(intensity),-1);
}
}
applyColorMap(hist2d_image, hist2d_image, COLORMAP_COOL);
imshow("H-Spro", hist2d_image);
//imwrite("E:/data-output/outputHSV2d_Hist.png", hist2d_image);
}
直方图均衡化
void QuickDemo::histogram_equal_demo(Mat& img)
{
Mat gray, dst;
cvtColor(img, gray, COLOR_BGR2GRAY);
equalizeHist(gray, dst);
imshow("dst",dst);
}
图像卷积操作
这是一个图像卷积的实例,会使得图像的灰度在所设定的窗口内进行卷积,使得产生一种模糊的效果
可以通过改变Size()来改变产生图标的效果.
void QuickDemo::blur_demo(Mat& img)
{
Mat dst;
blur(img, dst, Size(3, 3), Point(-1, -1));
imshow("dst",dst);
}
高斯模糊
产生的效果是中心位置的模糊是最大的,其他部分的是最小的,原理是通过改变其卷积和来产生的
产生一个中心化模糊效应
void QuickDemo::Gusin_demo(Mat &img)
{
Mat dst;
GaussianBlur(img,dst,Size(5,5),15);
imshow("dst", dst);
}
高斯双边模糊
参数说明:
-参数InputArray表示输入图像Mat对象
-参数OutputArray表示模糊之后输出Mat对象
-参数d表示双边滤波时候中心到周围像素距离
-参数sigmaColor表示高斯核中颜色值标准方差
-参数sigmaSpace表示高斯核中空间的标准方差
-参数borderType表示边缘的处理方法
一共六个参数,其中如果参数d没有申明的话或者是负数的话就从sigmaSpace中计算得到即可。常见的d取值为15或者20如果过大会导致运算时间较长。
void QuickDemo::Gusin_double_demo(Mat& img)
{
Mat dst;
bilateralFilter(img,dst,0,100,10);
imshow("dst",dst);
}
高斯双边滤波经常被用来实现图像美化类APP用来做高斯磨皮核心算法,然后基于SOBEL算子进行叠加处理,通过高斯模糊得到最终结果。效果异常明显,是一个不错的选择。
滤波函数filter2D
参数说明
-参数InputArray表示输入图像Mat对象
-参数OutputArray表示模糊之后输出Mat对象
-参数d表输出图像的深度,-1表示跟输入图像深度相同。
-参数kernel表示自定义的Mat对象,卷积核或者算子。
-参数Point表示锚定的位置,Point(-1, -1)表示默认为卷积核中心位置。
-参数delta表示卷积处理之后的每个像素值是否加上常量delta,默认0.0表示不加上额外值到处理后的像素值上。
-参数borderType表示边缘像素的处理方式,默认为BORDER_DEFAULT。
通过定义不同的卷积核、filter2D函数可以实现卷积的各种功能、包括模糊、锐化、边缘提取等。下面我们就来一一通过代码演示
void QuickDemo::blur_function(Mat& src)
{
//使用filter2D函数以及各种常见算子对图像进行操作
//1.模糊操作
/*
int ksize = 5;//设定卷积面积,模糊的程度与这个算子有关,越大越模糊
Mat dst;
Mat kernel = Mat::ones(ksize, ksize, CV_32F) / (float)(ksize * ksize);
filter2D(src,dst,-1,kernel,Point(-1,-1),0.0,4);
//注意用法:-1指的是深度是否保持一致 Point(-1,-1)表示瞄定的点在中间
imshow("模糊处理", dst);
*/
//2.实现边缘提取
/*
Mat dst;
Mat kernel = (Mat_<char>(3, 3) << -1, -1, -1, -1, 8, -1, -1, -1, -1);//设定一个算子
filter2D(src, dst,-1,kernel,Point(-1,-1),0.0,4);
imshow("边缘提取", dst);
*/
//3.实现图像的锐化
/*
Mat dst;
Mat kernel = (Mat_<char>(3, 3) << -1, -1, -1, -1, 9, -1,-1,-1,-1);
filter2D(src, dst, -1, kernel, Point(-1, - 1),0.0, 4);
imshow("图像锐化", dst);
*/
//4.Robot算子
/*
Mat dst;
Mat kernel = (Mat_<char>(2, 2) <<-1,0,0,1 );
filter2D(src, dst, -1, kernel, Point(-1, -1), 0.0, 4);
imshow("Robot算子", dst);
*/
//5.Sobel算子效果
Mat dst;
Mat kernel = (Mat_<char>(3, 3) << 1, 2, 1, 0, 0, 0, -1, -2, -1);
filter2D(src, dst, -1, kernel, Point(- 1, -1), 0.0, 4);
imshow("sobel算子", dst);
}