我們將從以下三個方面來實現空域增強:
一、圖象灰度變換;
二、圖象平滑;
三、圖象銳化;
一、圖象灰度變換;
(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<float>(i);
int intensity = saturate_cast<int>(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<uchar>(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<uchar>(i);
uchar* data2 = grayImg.ptr<uchar>(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<float>(i, 0) / dMax * 0.9 * height; // 最高顯示爲畫布的90%
cv::rectangle(canvas,
cv::Point(static_cast<int>((i - 1) * thickness), height),
cv::Point(static_cast<int>(i * thickness), static_cast<int>(height - h)),
color,
static_cast<int>(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<float>(i, 0) > minValue)
{
grayMin = static_cast<uchar>(i);
break;
}
}
// 求右邊界
uchar grayMax = 0;
for (int i = hist.rows - 1; i >= 0; --i)
{
if (hist.at<float>(i, 0) > minValue)
{
grayMax = static_cast<uchar>(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<uchar>(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<uchar>(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<uchar>(j, i) = 255; //at方法需要指定Mat變量返回值類型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at<cv::Vec3b>(j, i)[0] = 255; //cv::Vec3b爲opencv定義的一個3個值的向量類型
image.at<cv::Vec3b>(j, i)[1] = 255; //[]指定通道,B:0,G:1,R:2
image.at<cv::Vec3b>(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<uchar>(j, i) = 0; //at方法需要指定Mat變量返回值類型,如uchar等
}
else if (image.type() == CV_8UC3) { // color image
image.at<cv::Vec3b>(j, i)[0] = 0; //cv::Vec3b爲opencv定義的一個3個值的向量類型
image.at<cv::Vec3b>(j, i)[1] = 0; //[]指定通道,B:0,G:1,R:2
image.at<cv::Vec3b>(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<Vec3b>(i, j)[0] = (src.at<Vec3b>(i, j)[0] + src.at<Vec3b>(i - 1, j - 1)[0] + src.at<Vec3b>(i - 1, j)[0] + src.at<Vec3b>(i, j - 1)[0] +
src.at<Vec3b>(i - 1, j + 1)[0] + src.at<Vec3b>(i + 1, j - 1)[0] + src.at<Vec3b>(i + 1, j + 1)[0] + src.at<Vec3b>(i, j + 1)[0] +
src.at<Vec3b>(i + 1, j)[0]) / 9;
dst.at<Vec3b>(i, j)[1] = (src.at<Vec3b>(i, j)[1] + src.at<Vec3b>(i - 1, j - 1)[1] + src.at<Vec3b>(i - 1, j)[1] + src.at<Vec3b>(i, j - 1)[1] +
src.at<Vec3b>(i - 1, j + 1)[1] + src.at<Vec3b>(i + 1, j - 1)[1] + src.at<Vec3b>(i + 1, j + 1)[1] + src.at<Vec3b>(i, j + 1)[1] +
src.at<Vec3b>(i + 1, j)[1]) / 9;
dst.at<Vec3b>(i, j)[2] = (src.at<Vec3b>(i, j)[2] + src.at<Vec3b>(i - 1, j - 1)[2] + src.at<Vec3b>(i - 1, j)[2] + src.at<Vec3b>(i, j - 1)[2] +
src.at<Vec3b>(i - 1, j + 1)[2] + src.at<Vec3b>(i + 1, j - 1)[2] + src.at<Vec3b>(i + 1, j + 1)[2] + src.at<Vec3b>(i, j + 1)[2] +
src.at<Vec3b>(i + 1, j)[2]) / 9;
}
else {//邊緣賦值
dst.at<Vec3b>(i, j)[0] = src.at<Vec3b>(i, j)[0];
dst.at<Vec3b>(i, j)[1] = src.at<Vec3b>(i, j)[1];
dst.at<Vec3b>(i, j)[2] = src.at<Vec3b>(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<double>::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<uchar>(i)[j] + generateGaussianNoise(2, 0.8) * 32;
if (val < 0)
val = 0;
if (val > 255)
val = 255;
resultImage.ptr<uchar>(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<Vec3b>(i, j)[0] = Median(src.at<Vec3b>(i, j)[0], src.at<Vec3b>(i + 1, j + 1)[0],
src.at<Vec3b>(i + 1, j)[0], src.at<Vec3b>(i, j + 1)[0], src.at<Vec3b>(i + 1, j - 1)[0],
src.at<Vec3b>(i - 1, j + 1)[0], src.at<Vec3b>(i - 1, j)[0], src.at<Vec3b>(i, j - 1)[0],
src.at<Vec3b>(i - 1, j - 1)[0]);
_dst.at<Vec3b>(i, j)[1] = Median(src.at<Vec3b>(i, j)[1], src.at<Vec3b>(i + 1, j + 1)[1],
src.at<Vec3b>(i + 1, j)[1], src.at<Vec3b>(i, j + 1)[1], src.at<Vec3b>(i + 1, j - 1)[1],
src.at<Vec3b>(i - 1, j + 1)[1], src.at<Vec3b>(i - 1, j)[1], src.at<Vec3b>(i, j - 1)[1],
src.at<Vec3b>(i - 1, j - 1)[1]);
_dst.at<Vec3b>(i, j)[2] = Median(src.at<Vec3b>(i, j)[2], src.at<Vec3b>(i + 1, j + 1)[2],
src.at<Vec3b>(i + 1, j)[2], src.at<Vec3b>(i, j + 1)[2], src.at<Vec3b>(i + 1, j - 1)[2],
src.at<Vec3b>(i - 1, j + 1)[2], src.at<Vec3b>(i - 1, j)[2], src.at<Vec3b>(i, j - 1)[2],
src.at<Vec3b>(i - 1, j - 1)[2]);
}
else
_dst.at<Vec3b>(i, j) = src.at<Vec3b>(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
完.