1. 程式人生 > >(Opencv C++)數字影象處理——空域增強

(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

完.