I had another 10 minutes for my small archiving project this morning. Turns out I should have listened to my 7th grade1) math teacher: Trigonometry is actually important. And now that I have worked myself through all “Trigonometry for kids” pages google shows up, it turns out I don't need all this for OpenCV.
You basically only need getRotationMatrix2D to get the rotation matrix for the affine transformation and getRectSubPix to crop the rotated image. Thanks a lot to: http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/, it would have taken me a lot more minutes if I didn't see getRectSubPix.
In OpenCV this translates to (rest of code doesn't change):
// [...] for (int i = 0; i < contours.size(); i++) { // first calculate the area to remove small areas double area = contourArea(contours[i]); // you probably have to adjust the size of the area // as it depends on the size of the rectangle if (area > 10000) { // get the bounding box of this contour RotatedRect rect = minAreaRect(contours[i]); // matrices we'll use Mat M, rotated, cropped; // get angle and size from the bounding box float angle = rect.angle; Size rect_size = rect.size; // thanks to http://felix.abecassis.me/2011/10/opencv-rotation-deskewing/ if (rect.angle < -45.) { angle += 90.0; swap(rect_size.width, rect_size.height); } // http://opencv.willowgarage.com/documentation/cpp/geometric_image_transformations.html#cv-getrotationmatrix2d M = getRotationMatrix2D(rect.center, angle, 1.0); // http://opencv.willowgarage.com/documentation/cpp/geometric_image_transformations.html#cv-warpaffine warpAffine(src, rotated, M, src.size(), INTER_CUBIC); // yes yes, just a little scroll above getRotationMatrix2D: // http://opencv.willowgarage.com/documentation/cpp/geometric_image_transformations.html#cv-getrectsubpix getRectSubPix(rotated, rect_size, rect.center, cropped); imshow("cropped", cropped); waitKey(0); // write to file //std::stringstream ssfilename; //ssfilename << filename << i << ".jpg"; //imwrite(ssfilename.str(), cropped); } } [...]
and you end up with your extracted pictures:
So next thing is to put all this into a GUI! Forgot to mention I hacked a small Python Tkinter application to manually crop and rotate images: files/python/cropper.py.
Discussion
OpenCV makes our life easier…lol
Yep, but in the end it's sufficient to apply some smoothing (for example gaussian) and use adaptive thresholding. That yields much better results, than finding edges with a canny filter.
Automatically archiving pictures sounds interesting. There is something more u can do to add certain images to groups of interests with clustering algorthims :) maybe u will save time without to create folders and adding pictures to them ;)
Hey! I wish it was that easy to cluster images. The only thing, that quickly comes to my mind is to cluster by color intensities (and applying OpenCVs built in object detection algorithms).
In statistics you usually have some structured data and you try to find the distribution of the process behind it. The only thing that's probably done to the input data is some sort of preprocessing. Throw the outliers away, replace unknown values, normalize, …
But in computer vision you have to extract features from your image first:
That's the sort of things you have to deal with before applying a clustering algorithm to image data. Too many what if for a small project.