Ask Your Question
1

Extract parts of an image based on a raster mask?

asked 2015-08-28 18:18:42 -0600

hexdump gravatar image

Hi,

First of all I would like to say hi to the community because I'm a newcomer.

I have been reading about openCV for some days and I would like to use it in my jigsaw game (Android and IOS). What I need is to extract parts of an image based on pieces defined in another image (raster mask). The mask could be something like this:

image description

This image is defining just the outlines of each piece at each position. And I would like to cut the image based o this outlines. Can OpenCV help with this? I'm a bit lost right now. My intuition is saying openCV can do this but don't know how to achieve it.

Any help will be greatly appreciated.

Cheers.

edit retag flag offensive close merge delete

Comments

1

I understand your problem as your result will be 35 images? May be you can fill each mask with an index from 0 to 34

LBerger gravatar imageLBerger ( 2015-08-29 00:12:15 -0600 )edit

sure it is possible. like said above you will need 1 mask per piece type ( i can count only 21 uniques :) also those masks will need a border in the size of your nook, and you can just floodfill that border (even manually in paint or such)

but again, if you only need basic image processing, opencv might be far too heavy for you. (your clients will also need the opencv manager app from play store, which delivers the correct native c++ so's for your hardware)

berak gravatar imageberak ( 2015-08-29 03:41:33 -0600 )edit

Thaks for yor answers. The main reason to use OpenCV was to achieve a GPU solution. I think my software algoritm could work like this: 1) For all pixels do 2) Go to next pixel and check if transparency==255 or it was used in a previuos flood fill opration 3) If previous is true, return to 1 because we don't want this pxel. If false run a flood fill operation on this pixel and create an sprite from it based on the original image. We must keep a buffer to flag if pixel was used in a flood fill operation previously. Perhaps it could be the same temp buffer where we loaded the raster mask image.

I think this would work but I guess that it would be too slow. This is why I'm looking for a GPU solution using OpenCV.

Cheers.

hexdump gravatar imagehexdump ( 2015-08-29 04:20:23 -0600 )edit

just saying, there's usually decent opengl support on android. might still be an alternative for the sprite composition / alph / blitting.

creating the masks is actually an offline job, you don't have to do that from your app.

berak gravatar imageberak ( 2015-08-29 04:32:09 -0600 )edit

yes, this is true. The problem is that I tend to dig on things that I don't know how to do. And I have seen this method (the raster image mask)on other games and would like to come up with something like it :). Sorry to be so picky.

hexdump gravatar imagehexdump ( 2015-08-29 05:06:05 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2015-08-29 05:08:52 -0600

LBerger gravatar image

updated 2015-08-29 05:09:12 -0600

I 've write this code in opencv but I think like @berak may be you can do it without opencv specialy online part. (I have supposed your image have 3 channels)

int main (int argc,char **argv)
{
Mat x = imread("C:/Users/Laurent.PC-LAURENT-VISI/Downloads/puzzle.png",CV_LOAD_IMAGE_ANYCOLOR);
Mat img = imread("f:/lib/opencv/samples/data/lena.jpg",CV_LOAD_IMAGE_ANYCOLOR);
x = x(Rect(0,0,512,512));
Mat xg,xgConnex,xgConnexuc,xgD;
Mat stats,centroid;
cvtColor(x,xg,COLOR_RGB2GRAY);

threshold(xg,xg,50,255,CV_THRESH_BINARY_INV);
connectedComponentsWithStats(xg,xgConnex,stats,centroid,8,CV_16U);
Mat kernel = Mat::ones(3,3,CV_16U);
int nbIter=3;
dilate(xgConnex, xgD,Mat() , Point(-1,-1),nbIter);
cout << stats << "\n";
vector<Mat> puzzle;
puzzle.resize(stats.rows);
for (int i = 0;i< puzzle.size(); i++)
{
    puzzle[i] = Mat::zeros(stats.at<int>(i,3)+2*nbIter,stats.at<int>(i,2)+2*nbIter,img.type());
}
// ONLINE
for (int i = 0; i < img.rows; i++)
{
    uchar  *p = img.ptr(i);
    ushort *s = (ushort*)xgD.ptr(i);
    for (int j = 0; j < img.cols; j++, p += 3,s++)
    {
        int x=j - stats.at<int>(*s, 0)+nbIter,y= i - stats.at<int>(*s, 1)+nbIter;
        puzzle[*s].at<Vec3b>(y,x) = Vec3b(*p, p[1], p[2]);
    }
}

for (int i = 0;i< puzzle.size(); i++)
{
    imshow(format("puzzle %d",i),puzzle[i]);
}
waitKey();
}
edit flag offensive delete link more

Comments

Thanks for the code, it seems something I must dig

hexdump gravatar imagehexdump ( 2015-08-30 15:18:37 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2015-08-28 18:17:24 -0600

Seen: 2,099 times

Last updated: Aug 29 '15