//
// Created by yuqiong on 3/2/19.
// test drawing countours and then min bounding boxes
//
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
using namespace cv;
using namespace std;
Mat src_gray;
int thresh = 100;
RNG rng(12345);
void thresh_callback(int, void* );
int main( int argc, char** argv )
{
CommandLineParser parser( argc, argv, "{@input | ../data/stuff.jpg | input image}" );
Mat src = imread( parser.get<String>( "@input" ) );
if( src.empty() )
{
cout << "Could not open or find the image!\n" << endl;
cout << "usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
const char* source_window = "Source";
namedWindow( source_window );
imshow( source_window, src );
const int max_thresh = 255;
createTrackbar( "Canny thresh:", source_window, &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey();
return 0;
}
void thresh_callback(int, void* )
{
// binarize grayscale image to binary image as to get simpler contour
Mat binary_output;
threshold(src_gray, binary_output, 5, 255, THRESH_BINARY);
imshow("Binary output", binary_output);
vector<vector<Point> > contours;
findContours( binary_output, contours, RETR_TREE, CHAIN_APPROX_SIMPLE );
vector<vector<Point> > contours_poly(contours.size()); // store polygons for contours
// vector<Rect> rectangles(contours.size()); // stores bounding boxes
vector<RotatedRect> rectangles(contours.size()); // stores bounding boxes
// Rect minBoundRect; // minimum bounding box
RotatedRect minBoundRect; // minimum bounding box
// loop through and find smallest bounding boxes
float min_width = 0;
float min_height = 0;
int min_square_idx = 0;
std::cout << "Contour numbers " << contours.size() << std::endl;
for (size_t i = 0; i < contours.size(); i++)
{
// https://docs.opencv.org/3.4/da/d0c/tutorial_bounding_rects_circles.html
approxPolyDP(contours[i], contours_poly[i], 3, true );
// Rect rectangle = boundingRect(contours_poly[i]);
RotatedRect rectangle = minAreaRect(contours_poly[i]);
rectangles[i] = rectangle;
// Store the index position of the minimum square found
if ((rectangle.size.width <= min_width) && (rectangle.size.height <= min_height))
{
min_width = rectangle.size.width;
min_height = rectangle.size.height;
min_square_idx = i;
}
}
minBoundRect = rectangles[min_square_idx];
Point2f rect_points[4]; // get rotated rectangle points
minBoundRect.points( rect_points );
Point2f dst_points[4]; // destination points anchors
Point2f tl(0, 255);
dst_points[0] = tl;
Point2f bl(0, 0);
dst_points[1] = bl;
Point2f br(255, 0);
dst_points[2] = br;
Point2f tr(255, 255);
dst_points[3] = tr;
Mat M = getPerspectiveTransform(rect_points, dst_points); // translation matrix
Mat wrapped;
Size wrapped_size(256, 256);
warpPerspective(src_gray, wrapped, M, wrapped_size);
imshow("Wrapped binary output", wrapped);
// Write to file!
FileStorage out_file("test.xml", FileStorage::WRITE);
out_file << "trans" << M;
out_file.release();
// Read it back
FileStorage in_file("test.xml", FileStorage::READ);
Mat file_matrix;
in_file["trans"] >> file_matrix;
cout << file_matrix << endl;
in_file.release();
// now test invert
Mat invert;
Size invert_size(256, 256);
warpPerspective(wrapped, invert, file_matrix, invert_size, WARP_INVERSE_MAP);
imshow("Read back", invert);
}
draw ROI and scale and crop around contour.
Be the first to comment
You can use [html][/html], [css][/css], [php][/php] and more to embed the code. Urls are automatically hyperlinked. Line breaks and paragraphs are automatically generated.