Ask Your Question

Don't read my rectangle

asked 2016-02-10 09:05:09 -0500

xinyiman gravatar image

updated 2016-02-10 09:06:13 -0500

berak gravatar image

I adapted this code to read the white rectangle with the word 23-1965

But, it does not detect it sees a lot of other side dishes, but not what interests me. Who tells me where I'm wrong? Also attach the image to be processedimage description

 * Simple shape detector program.
 * It loads an image and tries to find simple shapes (rectangle, triangle, circle, etc) in it.
 * This program is a modified version of `squares.cpp` found in the OpenCV sample dir.
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <cmath>
#include <iostream>

using namespace std;

 * Helper function to find a cosine of angle between vectors
 * from pt0->pt1 and pt0->pt2
static double angle(cv::Point pt1, cv::Point pt2, cv::Point pt0)
    double dx1 = pt1.x - pt0.x;
    double dy1 = pt1.y - pt0.y;
    double dx2 = pt2.x - pt0.x;
    double dy2 = pt2.y - pt0.y;
    return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);

 * Helper function to display text in the center of a contour
void setLabel(cv::Mat& im, const std::string label, std::vector<cv::Point>& contour)
    int fontface = cv::FONT_HERSHEY_SIMPLEX;
    double scale = 0.4;
    int thickness = 1;
    int baseline = 0;

    cv::Size text = cv::getTextSize(label, fontface, scale, thickness, &baseline);
    cv::Rect r = cv::boundingRect(contour);

    cv::Point pt(r.x + ((r.width - text.width) / 2), r.y + ((r.height + text.height) / 2));
    cv::rectangle(im, pt + cv::Point(0, baseline), pt + cv::Point(text.width, -text.height), CV_RGB(255,255,255), CV_FILLED);
    cv::putText(im, label, pt, fontface, scale, CV_RGB(0,0,0), thickness, 8);

int main(int argc, char** argv)
    //cv::Mat src = cv::imread("polygon.png");
    cv::Mat src = cv::imread(argv[1]);
    if (src.empty())
        return -1;

    // Converti in scala di grigi
    cv::Mat gray;
    cv::cvtColor(src, gray, CV_BGR2GRAY);

    // Utilizzare Canny invece di soglia per la cattura di piazze con ombreggiatura gradiente
    cv::Mat bw;
    cv::Canny(gray, bw, 0, 50, 5);

    // Trova contorni
    std::vector<std::vector<cv::Point> > contours;
    cv::findContours(bw.clone(), contours, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_SIMPLE);   

    std::vector<cv::Point> approx;
    cv::Mat dst = src.clone();

    for(unsigned int l=0;l<contours.size();l++)

        if (contours[l].size() == 4 /*&& contours[l].size() <= 6*/)

                //cout << "# of contour points: " << contours[l].size() << endl ;
            cout << endl ;
                for(unsigned int k=0;k<contours[l].size();k++)
                //cout << "Point(x,y)=" << contours[l][k] << endl;
                cout << contours[l][k] << ";";
                //cout << " Area: " << contourArea(contours[l]) << endl;

    //cv::imshow("src", src);
    //cv::imshow("dst", dst);
    return 0;
edit retag flag offensive close merge delete

1 answer

Sort by » oldest newest most voted

answered 2016-02-10 22:31:59 -0500

Tetragramm gravatar image

Ok, it looks like you're getting there. Since the only text you can clearly see is the text you want to read, try taking a look at these parts of OpenCV:

Or you can take a look at this, which is written to find all the squares in a set of images. You can use that to narrow down the list of candidates.

edit flag offensive delete link more


I tried to compile the project:

But i have an error. Why? $ g++ squares.c++ -o squares -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_objdetect squares.c++:7:33: fatal error: opencv2/imgcodecs.hpp: File o directory non esistente #include "opencv2/imgcodecs.hpp" ^ compilation terminated.

xinyiman gravatar imagexinyiman ( 2016-02-11 15:25:40 -0500 )edit

Well, it seems you didn't specify the include directory containing OpenCV's include files. Go find whatever directory has "opencv2/imgcodecs.hpp" and add it to your command line as an include directory.

Tetragramm gravatar imageTetragramm ( 2016-02-11 15:31:12 -0500 )edit

The problem is that I do not find. I have given the command of ubuntu

sudo apt-get install libopencv-dev

but I did not get the desired result. Why?

xinyiman gravatar imagexinyiman ( 2016-02-12 03:32:43 -0500 )edit

Use this command to find the appropriate path: pkg-config --cflags opencv

At least according to random SO post. I have very little ubuntu experience.

Tetragramm gravatar imageTetragramm ( 2016-02-12 07:03:10 -0500 )edit

The problem is, i have a open cv 2, imgcodecs.hpp is insert into 3.

I have delete the include imgcodecs.hpp and when i compiled squares project return this error:

g++ squares.c++ -o squares -lopencv_core -lopencv_imgproc -lopencv_highgui -lopencv_objdetect >> app.txt squares.c++: In function ‘void drawSquares(cv::Mat&, const std::vector<std::vector<cv::point_<int> > >&)’: squares.c++:135:63: error: ‘LINE_AA’ was not declared in this scope polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3, LINE_AA);

why? Sorry to my terrible english

xinyiman gravatar imagexinyiman ( 2016-02-14 12:19:53 -0500 )edit

Ok, I went ahead. Now fill. And it works, manages to draw me the right rectangles.

But now I have a doubt. This is the function that draws rectangles

static void drawSquares( Mat& image, const vector<vector<point> >& squares ) { for( size_t i = 0; i < squares.size(); i++ ) { const Point* p = &squares[i][0]; int n = (int)squares[i].size(); polylines(image, &p, &n, 1, true, Scalar(0,255,0), 3/, LINE_AA/); }

//imshow(wndname, image);


How do I get to print the screen coordinates of these rectangles that draws?

xinyiman gravatar imagexinyiman ( 2016-02-14 12:41:11 -0500 )edit

Well, you have a vector of a vector of points. The outer vector is of squares, so the first square found would be squares[0], the second would be squares[1], ect. Each square is a vector of points, presumably 4 long. So the first point would be squares[0][0], the second would be squares[0][1] and so forth.

To print them on the image, you would use putText and a stringstream or something similar. To a file or console, you can just use the built in << operator, which will format the Point object appropriately.

Tetragramm gravatar imageTetragramm ( 2016-02-14 14:24:26 -0500 )edit

Oh, and if you want say, the center of the rectangle with the width and height and rotation angle, you put three of the four points into the constructor for RotatedRect and it will build one for you.

Tetragramm gravatar imageTetragramm ( 2016-02-14 14:26:05 -0500 )edit

Question Tools

1 follower


Asked: 2016-02-10 09:05:09 -0500

Seen: 1,214 times

Last updated: Feb 10 '16