Image scanning heuristic
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!
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.
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...
To use parallelism, inherit from the
ParallelLoopBody
class and implement thevirtual operator()(const cv::Range &amp; ) const
method. See this question for a working example.