一、马赛克效果
马赛克的实现原理是把图像上某个像素点一定范围邻域内的所有点用邻域内随机选取的一个像素点的颜色代替,这样可以模糊细节,但是可以保留大体的轮廓。
效果图如下
代码如下:
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:"<<mat.rows<<"cols:"<<mat.cols << "\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): (" <<i<<"," << j << ")\n" << m1 << endl;
}
}
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): (" <<i<<"," << j << ")\n" << m1 << endl;
}
}
imshow("马赛克", *data->m2);
data->startPt.x = -1;
data->startPt.y = -1;
data->m2->copyTo(*data->m1);
// waitKey(0);
}
}