Ask Your Question

# How I draw a rectangle by mosaic effect ?

This is my code

      #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

Mat image;
char click;
Point p1;
Point p2;
static void onMouse(int event, int x, int y, int, void*)
{

switch (event)
{
case CV_EVENT_LBUTTONDOWN:
if (click == 0){ // first click  top left
click = 1;
printf("%d %d", x, y);

}
else {          // second click  bottom right
click = 2;
printf("%d %d", x, y);
}

break;
case CV_EVENT_LBUTTONUP:
break;
}

}

void blurImage() {
// compute the block

int Num_cols = (p2.x - p1.x) / block;

int Num_row = (p1.x - p2.x) / block;

for (int i = 0; i < Num_row; i++)
{
for(int j = 0; j < Num_cols; j++)
{
int  x1 = p1.x + j * block;
int  y1 = p1.y + j * block;
int avg = sum / block*block;

// assign each pixel value by the block value

}
}
int main(void)
{
image = imread("C:/Users/faho0odywbas/Desktop/test.jpg");

namedWindow("Demo");
setMouseCallback("Demo", onMouse);

imshow("Demo", image);
waitKey(0);

return 0;
}


I want to draw a rectangle that's blur every thing inside it by mosaic effect, so my question is how to compute the block and assign each pixel value by the block value which are missing on my code

So the rectangle will be like this

edit retag close merge delete

## 1 answer

Sort by ยป oldest newest most voted

( i don't know if i am doing right but I can not stop myself from writing code as answer)

here the code you want almost done!

sample output : ( you can increase and decrease mosaic effect by pressing "i" and "d")

#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>

#include <iostream>

using namespace std;
using namespace cv;

bool selectObject = false;
Rect selection;
Point origin;
int msize = 5;
Mat image,blurredImage;

vector<Rect> blurredAreas;

static bool doMosaic( Mat img, int msize)
{
for (int i = 0; i < img.cols-msize; i+=msize)
for(int j = 0; j < img.rows-msize; j+=msize)
{
Rect r = Rect(i,j,msize,msize);
Mat mosaic = img( r );
mosaic.setTo(mean(mosaic));
}
return true;
}

static bool doBlur()
{
for(size_t i = 0; i< blurredAreas.size(); i++)
{
Mat roi = blurredImage(selection);
//GaussianBlur(roi,roi,Size(),5,5);
doMosaic(roi,msize);
}
imshow("Demo", blurredImage);
return true;
}

static void onMouse(int event, int x, int y, int, void*)
{
switch (event)
{
case CV_EVENT_LBUTTONDOWN:
origin = Point(x, y);
selectObject = true;
break;
case CV_EVENT_LBUTTONUP:
{
selectObject = false;
blurredAreas.push_back(selection);
doBlur();
break;
}
}

if (selectObject)
{
selection.x = MIN(x, origin.x);
selection.y = MIN(y, origin.y);
selection.width = std::abs(x - origin.x)+1;
selection.height = std::abs(y - origin.y)+1;
selection &= Rect(0, 0, image.cols, image.rows);

if ( selection.width > 0 && selection.height > 0)
{
Mat blurredImagecopy;
blurredImage.copyTo(blurredImagecopy);
Mat roi = blurredImagecopy(selection);
bitwise_not(roi, roi);
imshow("Demo", blurredImagecopy);
}
}
}

int main( int argc, char** argv )
{
image = imread( argv[1] );
if( image.empty() )                      // Check for invalid input
{
cout <<  "Could not open or find the image" << std::endl ;
return -1;
}
image.copyTo(blurredImage);

namedWindow("Demo");
setMouseCallback("Demo", onMouse );

imshow("Demo", image);

while( true )
{
int key = waitKey(0);

if( key == 27 )
break;

if( key == 's' ) // saves result image
{
imwrite("result.jpg",blurredImage);
}

if( key == 'i' ) // for increasing mosaic size
{
msize +=5;
image.copyTo(blurredImage);
doBlur();
}

if( key == 'd' ) // key 'd'  for decreasing mosaic size
{
msize = msize == 5 ? 5 : msize - 5;
image.copyTo(blurredImage);
doBlur();
}

if( key == 32 ) // space key for clear blurred areas
{
blurredAreas.clear();
image.copyTo(blurredImage);
doBlur();
}
}
return 0;
}

more

## Comments

@sturkmen many thanks for implementing and providing code solutions. That's really nice. Just one comment from my part, it would be also nice except the code to add some images showing the result. I think with that way it will be more helpful for the users ;-). Pictures are always more fancy, and they hit on the eye in better sense.

( 2015-09-18 13:55:47 -0500 )edit

dear @theodore thank you for your advise.I will follow your advice. i wanted to point out that sometimes users ask a ready code without showing any effort.

( 2015-09-18 14:33:45 -0500 )edit

is there a ready solution to do mosaic effect ? better than

static bool doMosaic( Mat img, int msize)
{
for (int i = 0; i < img.cols-msize; i+=msize)
for(int j = 0; j < img.rows-msize; j+=msize)
{
Rect r = Rect(i,j,msize,msize);
Mat mosaic = img( r );
mosaic.setTo(mean(mosaic));
}
return true;
}

( 2015-09-18 15:08:21 -0500 )edit

there is a nice example here, which partly in one step applies the same technique as you are using. The effect with the circles though, it is quite nice.

( 2015-09-18 17:06:57 -0500 )edit

Official site

GitHub

Wiki

Documentation

## Stats

Asked: 2015-09-18 10:39:35 -0500

Seen: 1,865 times

Last updated: Jan 01 '16