Я хочу обрезать ограничивающую рамку банкноты. У меня есть следующий код, который рисует ограничивающие рамки для контуров в изображении. С нарисованными прямоугольниками я хочу обрезать самый большой прямоугольник. Может ли кто-нибудь указать мне, как я могу это сделать.
У меня есть следующий код.
#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace cv;
using namespace std;
Mat src; Mat src_gray;
int thresh = 100;
int max_thresh = 255;
RNG rng(12345);
/// Function header
void thresh_callback(int, void* );
/**
* @function main
*/
int main( int, char** argv )
{
/// Load source image and convert it to gray
src = imread( "image_of_the_currency_note.jpg", 1 );
/// Convert image to gray and blur it
cvtColor( src, src_gray, COLOR_BGR2GRAY );
blur( src_gray, src_gray, Size(3,3) );
/// Create Window
const char* source_window = "Source";
namedWindow( source_window, WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Threshold:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );
waitKey(0);
return(0);
}
/**
* @function thresh_callback
*/
void thresh_callback(int, void* )
{
Mat threshold_output;
vector<vector<Point> > contours;
vector<Vec4i> hierarchy;
/// Detect edges using Threshold
threshold( src_gray, threshold_output, thresh, 255, THRESH_BINARY );
/// Find contours
findContours( threshold_output, contours, hierarchy, RETR_TREE, CHAIN_APPROX_SIMPLE, Point(0, 0) );
/// Approximate contours to polygons + get bounding rects
vector<vector<Point> > contours_poly( contours.size() );
vector<Rect> boundRect( contours.size() );
//vector<Point2f>center( contours.size() );
//vector<float>radius( contours.size() );
for( size_t i = 0; i < contours.size(); i++ )
{ approxPolyDP( Mat(contours[i]), contours_poly[i], 3, true );
boundRect[i] = boundingRect( Mat(contours_poly[i]) );
}/// Draw polygonal contour + bonding rects
Mat drawing = Mat::zeros( threshold_output.size(), CV_8UC3 );
for( size_t i = 0; i< contours.size(); i++ )
{
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
drawContours( drawing, contours_poly, (int)i, color, 1, 8, vector<Vec4i>(), 0, Point() );
rectangle( drawing, boundRect[i].tl(), boundRect[i].br(), color, 2, 8, 0 );
}
/// Show in a window
namedWindow( "Contours", WINDOW_AUTOSIZE );
imshow( "Contours", drawing );
}
Изображения прилагаются здесь. «image_of_the_currency_note» является исходным изображением, а «bounding_box_drawn_for_the_contours_in_the_currency_note» показывает ограничивающие рамки, нарисованные для исходного изображения. Я хочу получить самую большую ограничивающую рамку на изображении для объекта OpenCV Mat.
http://oi57.tinypic.com/wjcade.jpg — image_of_the_currency_note
http://oi57.tinypic.com/2cqzbsh.jpg — bounding_box_drawn_for_the_contours_in_the_currency_note
Если бы кто-то мог показать мне, как это сделать, это было бы очень полезно.
Благодарю.
Просто проверьте это boundRect[i].width > threshold && boundRect[i].height > threshold
, Порог может составлять треть размера изображения. Итак, если boundRect[i]
проходит условие, затем сохраняет его, иначе откажитесь от него. Таким образом, вы сможете получить самый большой прямоугольник.
Другой метод
Каждый ваш контур состоит из четырех точек (например, A, B, C, D) прямоугольника. Вам просто нужно извлечь значения координат x и y каждой точки контура.
После извлечения значений x и y для каждой точки вам просто нужно установить условие, что if (расстояние между двумя последующими точками> определенное значение) сохранит этот контур, иначе откажется от него.
Например: просто проверьте, если (B.x — A.x> 100), то если true .. сохранить контур.
Я нашел функцию contourArea () в opencv и решил использовать ее для получения наибольшего контура и нарисовал ограничивающую рамку этого наибольшего контура.
int largest_area=0;
int largest_contour_index=0;
Rect bounding_rect;
for( size_t i = 0; i < contours.size(); i++ ) {
double a=contourArea( contours[i],false); // Find the area of contour
if(a>largest_area){
largest_area=a;
largest_contour_index=i; //Store the index of largest contour
bounding_rect=boundingRect(contours[i]); // Find the bounding rectangle for biggest contour
}
}
Scalar color = Scalar( rng.uniform(0, 255), rng.uniform(0,255), rng.uniform(0,255) );
//drawContours( src, contours,largest_contour_index, color, CV_FILLED, 8, hierarchy ); // Draw the largest contour using previously stored index.
rectangle(src, bounding_rect, Scalar(0,255,0),1, 8,0);