我们将从以下三个方面来实现空域增强:
一、图象灰度变换;
二、图象平滑;
三、图象锐化;
一、图象灰度变换;
(1)、显示直方图;
(2)、对灰度图像进行直方图均衡化;
(3)、对灰度图像进行直方图拉伸;
主要用到的库函数如下:
void calcHist( const Mat* images, int nimages,const int* channels, InputArray mask,OutputArray hist, int dims, const int* histSize,onst float** ranges, bool uniform = true, bool accumulate = false ); //计算直方图函数
void minMaxLoc(InputArray src, CV_OUT double* minVal, CV_OUT double* maxVal = 0, CV_OUT Point* minLoc = 0,CV_OUT Point* maxLoc = 0, InputArray mask = noArray());//得到一个矩阵的最大值,最小值函数
void rectangle(InputOutputArray img, Point pt1, Point pt2,const Scalar& color, int thickness = 1, int lineType = LINE_8, int shift = 0);//统计直方图函数。
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn = 0 );//将RGB图像转化为灰度图;
首先得到直方图函数如下:
// 得到图像的直方图
MatND getHistogram(Mat &image)
{
MatND hist;
int channels[] = { 0 };
int dims = 1;
int histSize[] = { 256 };
float granges[] = { 0, 255 };
const float *ranges[] = { granges };
calcHist(&image, 1, channels, Mat(), hist, dims, histSize, ranges);
return hist;
}
// 将图像直方图展示出来
Mat getHistogramImage(Mat &image)
{
MatND hist = getHistogram(image);
Mat showImage(256, 256, CV_8U, Scalar(0));
int i;
double maxValue = 0;
minMaxLoc(hist, 0, &maxValue, 0, 0);
for (i = 0; i < 256; i++)
{
float value = hist.at(i);
int intensity = saturate_cast(256 - 256 * (value / maxValue));
rectangle(showImage, Point(i, 256 - 1), Point((i + 1) - 1, intensity), Scalar(255));
}
return showImage;
}
效果图如下:
直方图均衡化:计算出直方图,遍历直方图,得到归一化直方图和积分图,以积分图为查找表得到均衡化后的图。
其函数如下:
//得到直方图均衡函数
Mat getHistogram_Equalization(Mat &image)
{
Mat grayImg;
cvtColor(image, grayImg, CV_RGB2GRAY);//将rgb图像转化为灰度图
int rowNumber = grayImg.rows;//得到行
int colNumber = grayImg.cols;//得到列
int sumNumber = rowNumber * colNumber;//得到图像整个像素个数
Mat dstImg(rowNumber, colNumber, CV_8UC1, Scalar(0, 0, 0));//初始化直方图均衡化后的图
double hist[256] = { 0.00 };//直方图
double dhist[256] = { 0.00 };//直方图归一化图
double Dhist[256] = { 0.00 };//直方图积分图,每一个像素点
for (int i = 0; i < rowNumber; i++)//遍历原始图像,得到直方图
{
uchar* data = grayImg.ptr(i);
for (int j = 0; j < colNumber; j++)
{
int temp = data[j];//得到图像像素值
hist[temp] = hist[temp] + 1;//将相应像素值在直方图中加1
}
}
for (int i = 0; i < 256; i++)//遍历直方图,得到归一化直方图和积分图
{
dhist[i] = hist[i] / sumNumber;//得到归一化图
for (int j = 0; j <= i; j++)
{
Dhist[i] = Dhist[i] + dhist[j]; //得到积分图
}
}
for (int i = 0; i < rowNumber; i++)//以积分图为查找表得到均衡化后的图
{
uchar* data1 = dstImg.ptr(i);
uchar* data2 = grayImg.ptr(i);
for (int j = 0; j < colNumber; j++)
{
int temp1 = data2[j]; //查找到原始图相应位置的像素值
int temp2 = (int)(Dhist[temp1] * 255); //在积分图中找到相应像素值的映射值
data1[j] = temp2;//将映射值赋值给目标图像相应值
}
}
return dstImg;
}
// 使用Rect绘制直方图
void drawHist_Rect(const cv::Mat& hist, cv::Mat& canvas, const cv::Scalar& color)
{
CV_Assert(!hist.empty() && hist.cols == 1);
CV_Assert(hist.depth() == CV_32F && hist.channels() == 1);
CV_Assert(!canvas.empty() && canvas.cols >= hist.rows);
const int width = canvas.cols;
const int height = canvas.rows;
// 获取最大值
double dMax = 0.0;
cv::minMaxLoc(hist, nullptr, &dMax);
// 计算直线的宽度
float thickness = float(width) / float(hist.rows);
// 绘制直方图
for (int i = 1; i < hist.rows; ++i)
{
double h = hist.at(i, 0) / dMax * 0.9 * height; // 最高显示为画布的90%
cv::rectangle(canvas,
cv::Point(static_cast((i - 1) * thickness), height),
cv::Point(static_cast(i * thickness), static_cast(height - h)),
color,
static_cast(thickness));
}
}
效果如下:
下面进行直方图拉伸:
直方图拉伸的流程如下:
•1.计算出直方图;
•2.计算出左边界值;
•3.计算出右边界值;
•4.进行直方图拉伸;
其函数如下:
// 直方图拉伸
// grayImage - 要拉伸的单通道灰度图像
// hist - grayImage的直方图
// minValue - 忽略像数个数小于此值的灰度级
void histStretch(cv::Mat& grayImage, const cv::Mat& hist, int minValue)
{
CV_Assert(!grayImage.empty() && grayImage.channels() == 1 && grayImage.depth() == CV_8U);
CV_Assert(!hist.empty() && hist.rows == 256 && hist.cols == 1 && hist.depth() == CV_32F);
CV_Assert(minValue >= 0);
// 求左边界
uchar grayMin = 0;
for (int i = 0; i < hist.rows; ++i)
{
if (hist.at(i, 0) > minValue)
{
grayMin = static_cast(i);
break;
}
}
// 求右边界
uchar grayMax = 0;
for (int i = hist.rows - 1; i >= 0; --i)
{
if (hist.at(i, 0) > minValue)
{
grayMax = static_cast(i);
break;
}
}
if (grayMin >= grayMax)
{
return;
}
const int w = grayImage.cols;
const int h = grayImage.rows;
for (int y = 0; y < h; ++y)
{
uchar* imageData = grayImage.ptr(y);
for (int x = 0; x < w; ++x)
{
if (imageData[x] < grayMin)
{
imageData[x] = 0;
}
else if (imageData[x] > grayMax)
{
imageData[x] = 255;
}
else
{
imageData[x] = static_cast(std::round((imageData[x] - grayMin) * 255.0 / (grayMax - grayMin)));
}
}
}
}
//直方图拉伸函数
void getHistogram_Stetch(Mat& image)
{
Mat grayImage;
cvtColor(image, grayImage, COLOR_BGR2GRAY);
Mat hist;
Mat histCanvas(400, 512, CV_8UC3, Scalar(255, 255, 255));
int channels[1] = { 0 };
int histSize = 256;
float range[2] = { 0, 256 };
const float* ranges[1] = { range };
calcHist(&grayImage, 1, channels, Mat(), hist, 1, &histSize, ranges);
drawHist_Rect(hist, histCanvas, Scalar(255, 0, 0));
// 显示原始灰度图像及其直方图
imshow("Gray image", grayImage);
imshow("Gray image's histogram", histCanvas);
// 直方图拉伸
cv::Mat grayImageStretched = grayImage.clone();
histStretch(grayImageStretched, hist, 20);
// 计算直方图并绘制
cv::Mat histStretched;
cv::Mat histCanvasStretched(400, 512, CV_8UC3, cv::Scalar(255, 255, 255));
cv::calcHist(&grayImageStretched, 1, channels, cv::Mat(), histStretched, 1, &histSize, ranges);
drawHist_Rect(histStretched, histCanvasStretched, cv::Scalar(255, 0, 0));
// 显示拉伸后的灰度图像及其直方图
cv::imshow("Stretched image", grayImageStretched);
cv::imshow("Stretched image's histogram", histCanvasStretched);
}
其效果图如下:
二、图象平滑;
1、均值滤波;
2、高斯滤波;
3、中值滤波;
主要用到的库函数如下:
CV_EXPORTS_W void medianBlur( InputArray src, OutputArray dst, int ksize );//中值滤波
CV_EXPORTS_W void GaussianBlur( InputArray src, OutputArray dst, Size ksize,double sigmaX, double sigmaY = 0, int borderType = BORDER_DEFAULT );//高斯滤波
CV_EXPORTS_W void blur( InputArray src, OutputArray dst, Size ksize, Point anchor = Point(-1,-1), int borderType = BORDER_DEFAULT );//均值滤波
1.均值滤波
•均值滤波:线性平均滤波器,它通过求窗口内所有像素的平均值来得到中心像素点的像素值,就比如下图:
均值滤波程序如下:
//盐噪声
void salt_noise(Mat image, int n)
{
int i, j;
for (int k = 0; k < n / 2; k++) {
// rand() is the random number generator
i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
j = std::rand() % image.rows;
if (image.type() == CV_8UC1) { // gray-level image
image.at(j, i) = 255; //at方法需要指定Mat变量返回值类型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at(j, i)[0] = 255; //cv::Vec3b为opencv定义的一个3个值的向量类型
image.at(j, i)[1] = 255; //[]指定通道,B:0,G:1,R:2
image.at(j, i)[2] = 255;
}
}
}
//椒噪声
void pepper_noise(Mat image, int n)
{
int i, j;
for (int k = 0; k < n; k++) {
// rand() is the random number generator
i = std::rand() % image.cols; // % 整除取余数运算符,rand=1022,cols=1000,rand%cols=22
j = std::rand() % image.rows;
if (image.type() == CV_8UC1) { // gray-level image
image.at(j, i) = 0; //at方法需要指定Mat变量返回值类型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at(j, i)[0] = 0; //cv::Vec3b为opencv定义的一个3个值的向量类型
image.at(j, i)[1] = 0; //[]指定通道,B:0,G:1,R:2
image.at(j, i)[2] = 0;
}
}
}
//均值滤波
void AverFiltering(const Mat &src, Mat &dst) {
if (!src.data) return;
//at访问像素点
for (int i = 1; i < src.rows; ++i)
for (int j = 1; j < src.cols; ++j) {
if ((i - 1 >= 0) && (j - 1) >= 0 && (i + 1) < src.rows && (j + 1) < src.cols) {//边缘不进行处理
dst.at(i, j)[0] = (src.at(i, j)[0] + src.at(i - 1, j - 1)[0] + src.at(i - 1, j)[0] + src.at(i, j - 1)[0] +
src.at(i - 1, j + 1)[0] + src.at(i + 1, j - 1)[0] + src.at(i + 1, j + 1)[0] + src.at(i, j + 1)[0] +
src.at(i + 1, j)[0]) / 9;
dst.at(i, j)[1] = (src.at(i, j)[1] + src.at(i - 1, j - 1)[1] + src.at(i - 1, j)[1] + src.at(i, j - 1)[1] +
src.at(i - 1, j + 1)[1] + src.at(i + 1, j - 1)[1] + src.at(i + 1, j + 1)[1] + src.at(i, j + 1)[1] +
src.at(i + 1, j)[1]) / 9;
dst.at(i, j)[2] = (src.at(i, j)[2] + src.at(i - 1, j - 1)[2] + src.at(i - 1, j)[2] + src.at(i, j - 1)[2] +
src.at(i - 1, j + 1)[2] + src.at(i + 1, j - 1)[2] + src.at(i + 1, j + 1)[2] + src.at(i, j + 1)[2] +
src.at(i + 1, j)[2]) / 9;
}
else {//边缘赋值
dst.at(i, j)[0] = src.at(i, j)[0];
dst.at(i, j)[1] = src.at(i, j)[1];
dst.at(i, j)[2] = src.at(i, j)[2];
}
}
}
int main()
{
Mat srcImage = imread("1.jpg");
namedWindow("【原始图】", 1);
imshow("【原始图】", srcImage);
/*********************对图像进行椒盐化并进行均值滤波****************/
Mat image1(srcImage.size(), srcImage.type());
Mat image2;
salt_noise(srcImage, 4000);
pepper_noise(srcImage, 4000);
imshow("椒盐图【效果图】", srcImage);
AverFiltering(srcImage, image1);
blur(srcImage, image2, Size(3, 3));//openCV库自带的均值滤波函数
imshow("自定义均值滤波", image1);
imshow("openCV自带的均值滤波", image2);
}
效果图如下:
2.高斯滤波:
•对自备图片利用二维高斯模板,对其进行加权平滑滤波,并比较其效果
•高斯滤波是一种线性平滑滤波,适用于消除高斯噪声,广泛应用于图像处理的减噪过程
程序如下:
//得到高斯噪声
double generateGaussianNoise(double mu, double sigma)
{
//定义一个特别小的值
const double epsilon = numeric_limits::min();//返回目标数据类型能表示的最逼近1的正数和1的差的绝对值
static double z0, z1;
static bool flag = false;
flag = !flag;
//flag为假,构造高斯随机变量
if (!flag)
return z1 * sigma + mu;
double u1, u2;
//构造随机变量
do
{
u1 = rand()*(1.0 / RAND_MAX);
u2 = rand()*(1.0 / RAND_MAX);
} while (u1 <= epsilon);
//flag为真构造高斯随机变量X
z0 = sqrt(-2.0*log(u1))*cos(2 * CV_PI * u2);
z1 = sqrt(-2.0*log(u1))*sin(2 * CV_PI * u2);
return z1 * sigma + mu;
}
//为图像添加高斯噪声
Mat addGaussianNoise(Mat& srcImage)
{
Mat resultImage = srcImage.clone(); //深拷贝,克隆
int channels = resultImage.channels(); //获取图像的通道
int nRows = resultImage.rows; //图像的行数
int nCols = resultImage.cols*channels; //图像的总列数
//判断图像的连续性
if (resultImage.isContinuous()) //判断矩阵是否连续,若连续,我们相当于只需要遍历一个一维数组
{
nCols *= nRows;
nRows = 1;
}
for (int i = 0; i < nRows; i++)
{
for (int j = 0; j < nCols; j++)
{ //添加高斯噪声
int val = resultImage.ptr(i)[j] + generateGaussianNoise(2, 0.8) * 32;
if (val < 0)
val = 0;
if (val > 255)
val = 255;
resultImage.ptr(i)[j] = (uchar)val;
}
}
return resultImage;
}
int main()
{
Mat srcImage = imread("1.jpg");
namedWindow("【原始图】", 1);
imshow("【原始图】", srcImage);
/*********************对图像添加高斯噪声并进行高斯滤波**************/
Mat GaussianshowImage,GaussianshowImage_1;
GaussianshowImage_1 = addGaussianNoise(srcImage);
imshow("高斯噪声【效果图】", GaussianshowImage_1);
GaussianBlur(GaussianshowImage_1, GaussianshowImage, Size(3, 3), 1);
imshow("高斯滤波【效果图】", GaussianshowImage);
}
3.中值滤波:
•中值滤波:由此我们可以应用到图像处理中。依然我们在图像中去3*3的矩阵,里面有9个像素点,我们将9个像素进行排序,最后将这个矩阵的中心点赋值为这九个像素的中值。
其程序如下:
//求九个数的中值
uchar Median(uchar n1, uchar n2, uchar n3, uchar n4, uchar n5,uchar n6, uchar n7, uchar n8, uchar n9)
{
uchar arr[9];
arr[0] = n1;
arr[1] = n2;
arr[2] = n3;
arr[3] = n4;
arr[4] = n5;
arr[5] = n6;
arr[6] = n7;
arr[7] = n8;
arr[8] = n9;
for (int gap = 9 / 2; gap > 0; gap /= 2)//希尔排序
for (int i = gap; i < 9; ++i)
for (int j = i - gap; j >= 0 && arr[j] > arr[j + gap]; j -= gap)
swap(arr[j], arr[j + gap]);
return arr[4];//返回中值
}
//中值滤波函数
void MedianFlitering(const Mat &src, Mat &dst)
{
if (!src.data)return;
Mat _dst(src.size(), src.type());
for (int i = 0; i < src.rows; ++i)
for (int j = 0; j < src.cols; ++j)
{
if ((i - 1) > 0 && (i + 1) < src.rows && (j - 1) > 0 && (j + 1) < src.cols)
{
_dst.at(i, j)[0] = Median(src.at(i, j)[0], src.at(i + 1, j + 1)[0],
src.at(i + 1, j)[0], src.at(i, j + 1)[0], src.at(i + 1, j - 1)[0],
src.at(i - 1, j + 1)[0], src.at(i - 1, j)[0], src.at(i, j - 1)[0],
src.at(i - 1, j - 1)[0]);
_dst.at(i, j)[1] = Median(src.at(i, j)[1], src.at(i + 1, j + 1)[1],
src.at(i + 1, j)[1], src.at(i, j + 1)[1], src.at(i + 1, j - 1)[1],
src.at(i - 1, j + 1)[1], src.at(i - 1, j)[1], src.at(i, j - 1)[1],
src.at(i - 1, j - 1)[1]);
_dst.at(i, j)[2] = Median(src.at(i, j)[2], src.at(i + 1, j + 1)[2],
src.at(i + 1, j)[2], src.at(i, j + 1)[2], src.at(i + 1, j - 1)[2],
src.at(i - 1, j + 1)[2], src.at(i - 1, j)[2], src.at(i, j - 1)[2],
src.at(i - 1, j - 1)[2]);
}
else
_dst.at(i, j) = src.at(i, j);
}
_dst.copyTo(dst);//拷贝
}
int main()
{
Mat srcImage = imread("1.jpg");
namedWindow("【原始图】", 1);
imshow("【原始图】", srcImage);
/****************对图像加椒盐噪声,并进行中值滤波******************/
salt_noise(srcImage, 4000);
pepper_noise(srcImage, 4000);
imshow("【噪声图】", srcImage);
Mat Medical_showImage, Medical_showImage_1;
MedianFlitering(srcImage, Medical_showImage);
medianBlur(srcImage, Medical_showImage_1, 3);
imshow("自定义中值滤波处理后", Medical_showImage);
imshow("openCV自带的中值滤波", Medical_showImage_1);
}
其效果图如下:
三、图象锐化;
(1)、Sobel算子;
(2)、Laplacian算子;
所用到的库函数:
void Sobel( InputArray src, OutputArray dst, int ddepth,int dx, int dy, int ksize = 3, double scale = 1, double delta = 0,int borderType = BORDER_DEFAULT );//Sobel算子
void Laplacian( InputArray src, OutputArray dst, int ddepth,int ksize = 1, double scale = 1, double delta = 0,int borderType = BORDER_DEFAULT );//Laplacian算子
CV_EXPORTS_W void convertScaleAbs(InputArray src, OutputArray dst, double alpha = 1, double beta = 0);
CV_EXPORTS_W void addWeighted(InputArray src1, double alpha, InputArray src2, double beta, double gamma, OutputArray dst, int dtype = -1);
(1)、Sobel算子
1,利用3*3的Sobel算子对g11实施图象锐化
Sobel算子使用两个3*3的矩阵算子使用两个3*3的矩阵(图1)去和原始图片作卷积,分别得到横向G(x)和纵向G(y)的梯度值,如果梯度值大于某一个阈值,则认为该点为边缘点。
//Sobel算子
Mat getSobel(Mat &Image)
{
Mat dst_x, dst_y, dst;
Sobel(Image, dst_x, CV_16S,1, 0, 3,1,1,BORDER_DEFAULT);
convertScaleAbs(dst_x, dst_x);
imshow("对X方向求导【效果图】", dst_x);
Sobel(Image, dst_y, CV_16S,0, 1, 3,1,1, BORDER_DEFAULT);
convertScaleAbs(dst_y, dst_y);
imshow("对Y方向求导【效果图】", dst_y);
addWeighted( dst_x, 0.5, dst_y, 0.5, 0, dst);
return dst;
}
int main()
{
Mat srcImage_2 = imread("g14.tif");
namedWindow("【原始图】", 1);
imshow("【原始图】", srcImage_2);
/*********************对图像进行Sobel算子***************************/
Mat showImage, showImage_1;
showImage=getSobel(srcImage_2);
imshow("Sobel算子【效果图】", showImage);
}
效果图如下(这里我们直接显示x方向求偏导和对y方向上求的偏导的像素值):
(2)、Laplacian算子;
•利用3*3的Laplacian算子图象锐化:
• Laplace函数实现的方法是先用Sobel 算子计算二阶x和y导数,再求和:
其函数如下:
Mat getLaplacian(Mat &Image)
{
Mat Scr_Gray,showImage;
int kernel_size = 3;
int scale = 1;
int delta = 0;
int ddepth = CV_16S;
// 使用高斯滤波消除噪声
GaussianBlur(Image, Image, Size(3, 3), 0, 0, BORDER_DEFAULT);
// 转换为灰度图
cvtColor(Image, Scr_Gray, CV_RGB2GRAY);
// 使用Laplace函数
Mat abs_dst;
Laplacian(Scr_Gray, showImage, ddepth, kernel_size, scale, delta, BORDER_DEFAULT);
convertScaleAbs(showImage, abs_dst);
return abs_dst;
}
int main()
{
Mat srcImage_2 = imread("g14.tif");
namedWindow("【原始图】", 1);
imshow("【原始图】", srcImage_2);
/*********************对图像进行Laplacian算子***************************/
Mat showImage;
showImage = getLaplacian(srcImage_2);
imshow("Laplacian【效果图】", showImage);
}
其效果图如下:
最后的主函数如下:
int main()
{
Mat srcImage = imread("1.jpg");
Mat srcImage_1 = imread("g11.tif");
Mat srcImage_2 = imread("g14.tif");
if (!srcImage.data)
{
cout << "fail to load the image" << endl;
return -1;
}
if (!srcImage_1.data)
{
cout << "fail to load the image_1" << endl;
return -2;
}
if (!srcImage_2.data)
{
cout << "fail to load the image_2" << endl;
return -3;
}
//namedWindow("【原始图】", 1);
//imshow("【原始图】", srcImage);
/****************对图像加椒盐噪声,并进行中值滤波******************/
//salt_noise(srcImage, 4000);
//pepper_noise(srcImage, 4000);
//imshow("【噪声图】", srcImage);
//Mat Medical_showImage, Medical_showImage_1;
//MedianFlitering(srcImage, Medical_showImage);
//medianBlur(srcImage, Medical_showImage_1, 3);
//imshow("自定义中值滤波处理后", Medical_showImage);
//imshow("openCV自带的中值滤波", Medical_showImage_1);
/*******************************************************************/
/*********************对图像添加高斯噪声并进行高斯滤波**************/
//Mat GaussianshowImage,GaussianshowImage_1;
//GaussianshowImage_1 = addGaussianNoise(srcImage);
//imshow("高斯噪声【效果图】", GaussianshowImage_1);
//GaussianBlur(GaussianshowImage_1, GaussianshowImage, Size(3, 3), 1);
//imshow("高斯滤波【效果图】", GaussianshowImage);
/*******************************************************************/
/*********************对图像进行椒盐化并进行均值滤波****************/
//Mat image1(srcImage.size(), srcImage.type());
//Mat image2;
//salt_noise(srcImage, 4000);
//pepper_noise(srcImage, 4000);
//imshow("椒盐图【效果图】", srcImage);
//AverFiltering(srcImage, image1);
//blur(srcImage, image2, Size(3, 3));//openCV库自带的均值滤波函数
//imshow("自定义均值滤波", image1);
//imshow("openCV自带的均值滤波", image2);
/*******************************************************************/
/*********************对图像进行Sobel算子***************************/
//Mat showImage, showImage_1;
//showImage=getSobel(srcImage_2);
//imshow("Sobel算子【效果图】", showImage);
/*******************************************************************/
/*********************对图像进行Scharr算子***************************/
//Mat showImage;
//showImage = getScharr(srcImage_2);
//imshow("高通滤波【效果图】", showImage);
/*******************************************************************/
/*********************对图像进行Laplacian算子***************************/
/* Mat showImage;
showImage = getLaplacian(srcImage_2);
imshow("Laplacian【效果图】", showImage);*/
/*******************************************************************/
//Mat showImage = getHistogramImage(srcImage); //得到相应图片的直方图
//Mat showImage = getHistogram_Equalization(srcImage);//得到相应图片的直方图的均衡图
//imshow("【直方图】", showImage);
//getHistogram_Stetch(srcImage); //得到直方图拉伸之后的图像
/**********************测试代码*****************/
//Mat element = getStructuringElement(MORPH_RECT,Size(15,15));
//Mat dstImage;
//erode(srcImage, dstImage, element);
//imshow("腐蚀操作【效果图】", dstImage);
//blur(srcImage, dstImage,Size(7,7));
//imshow("均值滤波【效果图】", dstImage);
//Mat edge, grayImage;
//cvtColor(srcImage, grayImage, CV_BGR2GRAY);
//blur(grayImage, edge, Size(3, 3));
//Canny(edge, edge, 3, 9, 3);
//imshow("边缘检测【效果图】", edge);
/**********************************************/
waitKey(0);
return 0;
}
需要使用哪个函数自己使用就可以了。
CSDN下载地址
https://download.csdn.net/download/qq_40598185/10881668
完.