【笔记】Opencv处理图片:实现马赛克和毛玻璃滤镜效果

#include <core\core.hpp>
#include <highgui\highgui.hpp>
 
using namespace cv;
 
Mat imageSourceCopy; //原始图像
Mat imageSource; //原始图像拷贝
int neightbourHood = 9; //马赛克上每个方框的像素大小
 
RNG rng;
int randomNum; //邻域内随机值
 
Point ptL; //左键按下时坐标
Point ptR;  //右键按下时坐标
 
//鼠标回掉函数
void onMouse(int event, int x, int y, int flag, void *ustg);
 
int main()
{
	imageSourceCopy = imread("Test.jpg");
	imageSource = imageSourceCopy.clone();
	//imshow("马赛克", imageSourceCopy);
	namedWindow("马赛克");
	setMouseCallback("马赛克", onMouse);
	waitKey();
}
 
void onMouse(int event, int x, int y, int flag, void *ustg)
{
	if (event == CV_EVENT_LBUTTONDOWN)
	{
		ptL = Point(x, y);
	}
	if (event == CV_EVENT_LBUTTONUP)
	{
		//对鼠标画出的矩形框超出图像范围做处理,否则会越界崩溃
		x > imageSource.cols - 2 * neightbourHood ? x = imageSource.cols - 2 * neightbourHood : x = x;
		y > imageSource.rows - 2 * neightbourHood ? y = imageSource.rows - 2 * neightbourHood : y = y;
 
		//对鼠标从右下往右上画矩形框的情况做处理
		ptR = Point(x, y);
		Point pt = ptR;
		ptR.x < ptL.x ? ptR = ptL, ptL = pt : ptR = ptR;
		for (int i = 0; i < ptR.y - ptL.y; i += neightbourHood)
		{
			for (int j = 0; j < ptR.x - ptL.x; j += neightbourHood)
			{
				randomNum = rng.uniform(-neightbourHood / 2, neightbourHood / 2);
				Rect rect = Rect(j + neightbourHood + ptL.x, i + neightbourHood + ptL.y, neightbourHood, neightbourHood);
				Mat roi = imageSourceCopy(rect);
				Scalar sca = Scalar(
					imageSource.at<Vec3b>(i + randomNum + ptL.y, j + randomNum + ptL.x)[0],
					imageSource.at<Vec3b>(i + randomNum + ptL.y, j + randomNum + ptL.x)[1],
					imageSource.at<Vec3b>(i + randomNum + ptL.y, j + randomNum + ptL.x)[2]);
				Mat roiCopy = Mat(rect.size(), CV_8UC3, sca);
				roiCopy.copyTo(roi);
			}
		}
	}
	imshow("马赛克", imageSourceCopy);
	waitKey();
}

可以通过改变程序中neightbourHood参数的大小调整小矩形块的大小, 实现效果:

 

#include <core\core.hpp>
#include <highgui\highgui.hpp>
 
using namespace cv;
 
int main()
{
	Mat imageSource = imread("Test.jpg");
	Mat imageResult = imageSource.clone();
	RNG rng;
	int randomNum;
	int Number = 5;
 
	for (int i = 0; i < imageSource.rows - Number; i++)
		for (int j = 0; j < imageSource.cols - Number; j++)
		{
			randomNum = rng.uniform(0, Number);
			imageResult.at<Vec3b>(i, j)[0] = imageSource.at<Vec3b>(i + randomNum, j + randomNum)[0];
			imageResult.at<Vec3b>(i, j)[1] = imageSource.at<Vec3b>(i + randomNum, j + randomNum)[1];
			imageResult.at<Vec3b>(i, j)[2] = imageSource.at<Vec3b>(i + randomNum, j + randomNum)[2];
		}
	imshow("毛玻璃效果", imageResult);
	waitKey();
}

 实现效果:

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值