Image scanning heuristic

asked 2014-11-04 10:34:07 -0600

Doombot gravatar image

updated 2014-11-04 10:37:48 -0600

I have to scan an image with a window of a specific size (can't choose it but is smaller than the size of the image). So the size of the image and the size of the windows may change overtime; I may load a new image from time to time and the windows size might change after every complete scan.

So I need to devise an algorithm that tells me, from the input image and the window size, how much time I must slide the window horizontally and vertically to cover all of the pixels but with some level of overlap. I have already experimented on it and I found that if the resolution of the sliding is superior to a fourth of the window's dimensions (e.g. the windows is 100 wide so I must not slide it more than 25 px at a time), it is enough for the type of application I work on.

Of course, it is akin to ask "How much quarter-windows can I fit in the image?" Since there is not necessarily an integer windows in the image and that I can't scan the image with an half window, I needed to implement border case logic. Not sure if I am clear... Anyway, here is the code I have but I bust the matrix bounds...

    Mat scene;
    Mat window;
    ///
    //load the image, define the window's size, do some other stuff
    ///
    int window_height = window.rows;
    int window_width = window.cols;

    int scene_height = scene.rows;
    int scene_width = scene.cols;

    int stepX = window_width/4; 
    int stepY = window_height/4; 

    int n_width_win = ((scene_width - window_width)/(stepX)) +1;
    int n_height_win = ((scene_height - window_height)/(stepY)) +1 ;

        // create the coordinates of the corners of a rectangle, will be used somewhere
    int topleftX, topleftY, bottomrigthX, bottomrigthY;


    for (int w_counter = 0; w_counter <= n_width_win; w_counter++){

        for (int h_counter= 0; h_counter <= n_height_win; h_counter++) {


            topleftX = (w_counter)*stepX;
            topleftY = (h_counter)*stepY;


            // Border case, if the window bust the bounds of the scene image
                    // set the coordinates of the window so that it ends at the end 
                    // of the image
            if ((topleftX+window_width)>scene_width) topleftX = scene_width - window_width;
            if ((topleftY+window_height)>scene_height) topleftY = scene_height - window_height;

            bottomrigthX = topleftX + window_width;
            bottomrigthY = topleftY + window_height;

            for( int i = 0; i < some_relevant_variable ; i++ )
            {
                            //compute_some_stuff, a metric, etc.
                        }

    Mat scene_sub (scene, Rect( topleftX, topleftY, window_width, window_height));
    imshow("This is what is in the window /sub image", scene_sub);
    waitKey(0);
    }
}

Now I wonder if there isn't a more efficient way to do this. I think that it would be possible to "parallelize" both "h_counter" and "w_counter" loops since they are doing computation on independent sections of the scene image.

I understand this somewhat looks like I am trying to implement my own template matching, and in some way it is, only that I don't match a template but compute a specific metric, window by window. Well, if there is some way to hack template matching to do this, I am open to suggestions too!

edit retag flag offensive close merge delete

Comments

1

The arithmetic of finding out the number of overlapping sub-rectangles horizontally and vertically is no more difficult than an interview question. Just do the calculations with some small numbers, say, numbers less than 10. Draw some diagrams; take care to represent pixels as boxes (not just tick marks); also take care to avoid off-by-one errors. Finally, keep in mind that because the division is not always nicely rounded, you must allow a plus/minus one fluctuations in the amounts of overlap. If you still need help with the mathematics I will write an answer a few days later.

rwong gravatar imagerwong ( 2014-11-04 14:48:30 -0600 )edit

Yeah I will do the math on paper, it will help. But let's say that I solve this. What about parallelism? If anybody used par_for before...

Doombot gravatar imageDoombot ( 2014-11-05 08:05:13 -0600 )edit
1

To use parallelism, inherit from the ParallelLoopBody class and implement the virtual operator()(const cv::Range &amp;amp; ) const method. See this question for a working example.

rwong gravatar imagerwong ( 2014-11-06 14:31:01 -0600 )edit