(Opencv C++)數字影象處理——空域增強
我們將從以下三個方面來實現空域增強:
一、圖象灰度變換;
二、圖象平滑;
三、圖象銳化;
一、圖象灰度變換;
(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
完.