使用OpenCV实现马赛克效果

一、马赛克效果

马赛克的实现原理是把图像上某个像素点一定范围邻域内的所有点用邻域内随机选取的一个像素点的颜色代替,这样可以模糊细节,但是可以保留大体的轮廓。
效果图如下使用OpenCV实现马赛克效果_第1张图片

代码如下:

typedef struct UserData
{
	Point  startPt=Point(-1,-1);
	Mat* m1;
	Mat* m2;
}UserData;

void COpenCVDmeo::mosaic()
{
	Mat  image;
	image = imread(m_imagePath);
	showWindow("原图", image);
	UserData  data;
	data.m1=ℑ
	Mat  m2 = image.clone();
	data.m2 = &m2;
	namedWindow("马赛克", WINDOW_NORMAL);

	setMouseCallback("马赛克",&COpenCVDmeo::mosaicCallBack,(void *)(&data));
	imshow("马赛克", image);
	waitKey(0);
}

void COpenCVDmeo::mosaicCallBack(int event, int x, int y, int flags, void* userdata)
{
	UserData* data = static_cast<UserData*>(userdata);
	data->m1->copyTo(*data->m2);
	
	if (event == EVENT_LBUTTONDOWN) {
		data->startPt.x = x;
		data->startPt.y = y;
	}
	else  if(event == EVENT_MOUSEMOVE)
	{
	
		if (data->startPt.x<0||data->startPt.y<0)
				return;
		int dx = x - data->startPt.x;
		int dy = y - data->startPt.y;
		//rectangle(*data->m2, Rect(data->startPt, Point(x, y)), Scalar(255, 0, 0), 2);
		Mat mat = (*data->m2)(Rect(data->startPt, Point(x, y)));
		
	//	cout << "框选区域:"<<"rows:"<
		int len = 15;
			for (int j = 0; j + len <= mat.rows; j += len)
		{
				for (int i = 0; i + len <= mat.cols; i += len)
			{
				//cout << "通道数:" << mat.channels()<
				Mat m1 = mat(Rect(Point(i, j), Point(i + len, j + len)));
			//	cout << "原图:(i ,j): (" << i << "," << j << ")\n" << m1 << endl;
				for (int k = 0; k < len; k++)
				{
					for (int l = 0; l < len; l++)
					{
						m1.at<Vec3b>(k, l)[0] = m1.at<Vec3b>(0, 0)[0];
						m1.at<Vec3b>(k, l)[1] = m1.at<Vec3b>(0, 0)[1];
						m1.at<Vec3b>(k, l)[2] = m1.at<Vec3b>(0, 0)[2];
					}
				}
			//	cout << "转换后图:(i ,j): (" <
			}
		}
		imshow("马赛克", *data->m2);
	}
	else  if (event == EVENT_LBUTTONUP)
	{
		if (data->startPt.x < 0 || data->startPt.y < 0)
			return;
		int dx = x - data->startPt.x;
		int dy = y - data->startPt.y;
		//rectangle(*data->m2, Rect(data->startPt, Point(x, y)), Scalar(255, 0, 0), 2);
		Mat mat = (*data->m2)(Rect(data->startPt, Point(x, y)));
		//cout << "框选区域:\n" << mat << endl;

		int len = 15;
		for (int j = 0; j + len <= mat.rows; j += len)
		{
			for (int i = 0; i + len <= mat.cols; i += len)
			{
				//cout << "通道数:" << mat.channels() << endl;
				Mat m1 = mat(Rect(Point(i, j), Point(i + len, j + len)));
				//	cout << "原图:(i ,j): (" << i << "," << j << ")\n" << m1 << endl;
				for (int k = 0; k < len; k++)
				{
					for (int l = 0; l < len; l++)
					{
						m1.at<Vec3b>(k, l)[0] = m1.at<Vec3b>(0, 0)[0];
						m1.at<Vec3b>(k, l)[1] = m1.at<Vec3b>(0, 0)[1];
						m1.at<Vec3b>(k, l)[2] = m1.at<Vec3b>(0, 0)[2];
					}
				}
				//	cout << "转换后图:(i ,j): (" <
			}
		}
		imshow("马赛克", *data->m2);
		data->startPt.x = -1;
		data->startPt.y = -1;
		data->m2->copyTo(*data->m1);
	//	waitKey(0);
	}
}

你可能感兴趣的:(Opencv,学习之路,opencv,人工智能,计算机视觉)