2020-12-28 learning opencv3: 十:Smoothing

2020-11-30 03_空域圖像處理 筆記

 

Smoothing, also called blurring as depicted in Figure 10-6, is a simple and frequently
used image-processing operation. There are many reasons for smoothing, but it is
often done to reduce noise or camera artifacts.



Simple Blur and the Box Filter
 

The simple blur operation is provided by cv::blur(). Each pixel in the output is the simple mean of all of the pixels in a window (i.e., the kernel), around the correspond‐ing pixel in the input.
 

#include <opencv2/opencv.hpp>

using namespace cv;
int blurType = 0;
Mat src;

void copyPixel(const Mat& src, Mat& dst)
{
	for (size_t i = 0; i < src.rows; i++)
	{
		for (size_t j = 0; j < src.cols; j++)
		{
			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];  //紅是通道
		}
	}
}

void blurTest(Mat& src)
{
	Mat dstBlur = src.clone();
	blur(src, dstBlur, Size(5, 5));

	Mat imageWarp = Mat(Size(src.cols, src.rows), src.type());
	Mat warp = (Mat_<float>(2, 3) << 1, 0, src.cols , 0, 1, 0);
	//cv::Mat t_mat = cv::Mat::zeros(2, 3, CV_32FC1);
	//t_mat.at<float>(0, 0) = 1;
	//t_mat.at<float>(0, 2) = 20; //水平平移量
	//t_mat.at<float>(1, 1) = 1;
	//t_mat.at<float>(1, 2) = 10; //豎直平移量
	warpAffine(dstBlur, imageWarp, warp, Size(2 * src.cols, src.rows));
	imshow("image", imageWarp);

	copyPixel(src, imageWarp);
	imshow("image", imageWarp);
	waitKey();
}

void boxFilterTest(Mat& src)
{
	Mat dstBlur = src.clone();
	boxFilter(src, dstBlur, -1, Size(5, 5), Point(-1, 1), false);

	Mat imageWarp = Mat(Size(src.cols, src.rows), src.type());
	Mat warp = (Mat_<float>(2, 3) << 1, 0, src.cols, 0, 1, 0);
	//cv::Mat t_mat = cv::Mat::zeros(2, 3, CV_32FC1);
	//t_mat.at<float>(0, 0) = 1;
	//t_mat.at<float>(0, 2) = 20; //水平平移量
	//t_mat.at<float>(1, 1) = 1;
	//t_mat.at<float>(1, 2) = 10; //豎直平移量
	warpAffine(dstBlur, imageWarp, warp, Size(2 * src.cols, src.rows));
	imshow("image", imageWarp);

	copyPixel(src, imageWarp);
	imshow("image", imageWarp);
	waitKey();
}

void medianFilterTest(Mat& src)
{
	Mat dstBlur = src.clone();
	medianBlur(src, dstBlur, 5);

	Mat imageWarp = Mat(Size(src.cols, src.rows), src.type());
	Mat warp = (Mat_<float>(2, 3) << 1, 0, src.cols, 0, 1, 0);

	warpAffine(dstBlur, imageWarp, warp, Size(2 * src.cols, src.rows));
	imshow("image", imageWarp);

	copyPixel(src, imageWarp);
	imshow("image", imageWarp);
	waitKey();
}

void myBlur(int, void*)
{
	Mat dstBlur;
	//printf("type is %d\n ", blurType);
	switch (blurType)
	{
	case 0:
		blur(src, dstBlur, Size(5, 5));
		break;

	case 1:
		boxFilter(src, dstBlur, -1, Size(5, 5), Point(-1, 1), false);
		break;

	case 2:
	  medianBlur(src, dstBlur, 5);
	  break;

	  For the Gaussian blur(an example kernel is shown in Figure 10 - 10), the parameter
		  ksize gives the widthand height of the filter window.The next parameter indicates
		  the sigma value(half width at half max) of the Gaussian kernel in the x - dimension.
		  The fourth parameter similarly indicates the sigma value in the y - dimension.If you
		  specify only the x value, and set the y value to 0 (its default value), then the yand x
		  values will be taken to be equal.
	case 3:
		GaussianBlur(src, dstBlur, Size(5, 5), 1, 1);
		break;

		Bilateral filtering is
			one operation from a somewhat larger class of image analysis operators known as
			edge - preserving smoothing.Bilateral filtering is most easily understood when contras‐
			ted to Gaussian smoothing.
	case 4:
		bilateralFilter(src, dstBlur, -1, 10, 1);
		break;

	default:
		break;
	}

	//if (blurType == 0)
	//{
	//	blur(src, dstBlur, Size(5, 5));
	//}
	//else if (blurType == 1)
	//{
	//	boxFilter(src, dstBlur, -1, Size(5, 5), Point(-1, 1), false);
	//}

	Mat imageWarp = Mat(Size(src.cols, src.rows), src.type());
	Mat warp = (Mat_<float>(2, 3) << 1, 0, src.cols, 0, 1, 0);

	warpAffine(dstBlur, imageWarp, warp, Size(2 * src.cols, src.rows));
	imshow("image", imageWarp);

	copyPixel(src, imageWarp);
	imshow("image", imageWarp);
	waitKey();
}


int main()
{
	//Mat src = imread("NWPULB.jpg", IMREAD_COLOR);
	 src = imread("NWPULB.jpg", IMREAD_COLOR);
	int width = src.cols / 6;
	int height = src.rows / 6;
	resize(src, src, Size(width, height));

	Mat image = Mat(Size(2*width, height), src.type());
	namedWindow("image", 1);
	imshow("image", image);

	if (src.empty())
	{
		std::cout << "Could not open or find the image!\n" << std::endl;
		return EXIT_FAILURE;
	}
	

	//1 blur
	//blurTest(src);

//The main difference between cv::box
//Filter() and cv::blur() is that the former can be run in an unnormalized mode
//(normalize = false), and that the depth of the output image dst can be controlled.
//(In the case of cv::blur(), the depth of dst will always equal the depth of src.) If the
//value of ddepth is set to - 1, then the destination image will have the same depth as
//the source; otherwise, you can use any of the usual aliases(e.g., CV_32F)

	 2 boxFilter
	//boxFilterTest(src);

	The median filter[Bardyn84] replaces each pixel by the median or “middle - valued”
		pixel(as opposed to the mean pixel) in a rectangular neighborhood around the center
		pixel.7 Results of median filtering are shown in Figure 10 - 9. Simple blurring by aver‐
		aging can be sensitive to noisy images, especially images with large isolated outlier
		values(e.g., shot noise in digital photography).Large differences in even a small
		number of points can cause a noticeable movement in the average value.Median fil‐
		tering is able to ignore the outliers by selecting the middle points.
	//3 Median Filter
	//medianFilterTest(src);

	The next smoothing filter, the Gaussian filter, is probably the most useful.Gaussian
		filtering involves convolving each point in the input array with a(normalized) Gaus‐
		sian kerneland then summing to produce the output array

	//4 All Filter
	
	createTrackbar("show", "image", &blurType, 4, myBlur);
	myBlur(0, 0);

	return 0;
}

 

 

 

 

 

 

 

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章