2

I would like to crop out an image from an existing image. I've taken an image and applied monochrome on it with threshold 98% using imagemagick (is this doable in openCV?)

The resulting image is this:

enter image description here

Now from this Image I would like to crop out another image so that the final image looks like this:

enter image description here

Question How can I do this in OpenCV? Note, the only reason I want to crop the image is so that I can use this answer to get the part of the text. If there is no need to crop out a new image and instead just concentrate on black part of the image to begin with, that would be great.

Community
  • 1
  • 1
birdy
  • 8,476
  • 22
  • 98
  • 170
  • It seems that you are trying to resize an image instead of crop it, is that correct? – Boyko Perfanov Apr 01 '13 at 13:52
  • @perfanoff birdy wants to crop it. Stack Overflow is resizing the images. [Before](http://i.stack.imgur.com/MKcXt.png). [After](http://i.stack.imgur.com/hMTnv.png). – Drew Dormann Apr 01 '13 at 14:06
  • @perfanoff that is correct. thanks for clarification. I am not trying to resize the image. – birdy Apr 01 '13 at 14:12

2 Answers2

5

If the text at the top and at the bottom are the regions that you want to crop out, if they are always at the same location the solution is easy: just set a ROI that ignores those areas:

#include <cv.h>
#include <highgui.h>

int main(int argc, char* argv[])
{
    cv::Mat img = cv::imread(argv[1]);
    if (img.empty())
    {
        std::cout << "!!! imread() failed to open target image" << std::endl;
        return -1;        
    }

    /* Set Region of Interest */

    int offset_x = 129;
    int offset_y = 129;

    cv::Rect roi;
    roi.x = offset_x;
    roi.y = offset_y;
    roi.width = img.size().width - (offset_x*2);
    roi.height = img.size().height - (offset_y*2);

    /* Crop the original image to the defined ROI */

    cv::Mat crop = img(roi);
    cv::imshow("crop", crop);
    cv::waitKey(0);

    cv::imwrite("noises_cropped.png", crop);

    return 0;
}

Output image:

If the position of the black rectangle, which is your area of interest, is not present on a fixed location then you might want to check out another approach: use the rectangle detection technique:

On the output above, the area you are interested will be 2nd largest rectangle in the image.

On a side note, if you plan to isolate the text later, a simple cv::erode() could remove all the noises in that image so you are left with the white box & text. Another technique to remove noises is to use cv::medianBlur().You can also explore cv::morphologyEx() to do that trick:

cv::Mat kernel = cv::getStructuringElement(cv::MORPH_ELLIPSE, cv::Size(7, 7), cv::Point(3, 3));
cv::morphologyEx(src, src, cv::MORPH_ELLIPSE, kernel);    

A proper solution might even be a combination of these 3. I've demonstrated a little bit of that on Extract hand bones from X-ray image.

Community
  • 1
  • 1
karlphillip
  • 87,606
  • 33
  • 227
  • 395
  • The title will always be around the same location. Meaning it will always be on top of the image. How can I set the ROI that ignores the top? I'm new to opencv...is there a sample program that shows ignoring some ROI of the image based on color... – birdy Apr 01 '13 at 17:53
  • ok thanks. I tried the `morphologyEx` technique and got this image: http://imageshack.us/a/img16/5506/screenshot20130401at203.png now i guess i need to figure out the coordinates where the big rectangle starts... – birdy Apr 01 '13 at 18:06
  • The rectangle detection technique is exactly what I need since the rectangle location won't always be the same. I will use that answer to come up with a solution. thanks – birdy Apr 01 '13 at 18:26
  • Is there something that can be done in c++ to avoid typing `cv::` in front of all variables and rather just type `Mat Point ` etc. – birdy Apr 01 '13 at 19:11
  • Yes, after the `#include` section, add: `using namespace cv;` – karlphillip Apr 01 '13 at 21:03
0

A simple solution: scan lines from top down, bottom up, left-right and right-left. Terminate when the number of dark pixels in the line exceeds 50% of the total amount of pixels in the line. This will give you the xmin, xmax, ymin, ymax coordinates to bound your cropping rectangle.

Boyko Perfanov
  • 2,859
  • 15
  • 32