1

I am trying to find the dimension of different objects.

Until now I was working with one object. When I tried to find dimension of a different object, I realized that I needed to change threshold1 value of Canny.

So my question is: how can I make my program to do that kind of adjustments for different objects automatically? So that I won't need to change anything manually. What kind of algorithm should I use?

Background will be same, camera's position will be fixed, we can assume that the lighting will be same.

For this picture I need a threshold1 value of 53 in order to find the edges.

bluePaper2.png

For this one, a value of 141 works pretty good.

hardDisk2.png

I couldn't find any values for this one, since its color is almost same as the background's.

bigPaper1.png

Here is my code:

#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, src_gray, src_blur;
Mat canny_output;

int canny_thresh = 53;
int canny_max_thresh = 200;
int canny_kernel = 3;
int canny_ratio = 3;
bool L2gradient = true;

char* source_window = "Source";
char* canny_window = "Canny";
char* contour_window = "Contours";

/** @function main */
int main(int argc, char** argv)
{
    /// Load source image and convert it to gray
    src = imread("bluePaper2.png", 1);

    /// Create Window   
    namedWindow(source_window, CV_WINDOW_AUTOSIZE);
    imshow(source_window, src);

    /// Convert image to gray and blur it
    cvtColor(src, src_gray, CV_BGR2GRAY);

    /// Reduce noise with a kernel 3x3
    blur(src_gray, src_blur, Size(3, 3));   

    /// Detect edges using Canny
    Canny(src_blur, canny_output, canny_thresh, canny_thresh * canny_ratio, canny_kernel, L2gradient);

    vector<vector<Point> > contours;
    vector<Vec4i> hierarchy;

    /// Find contours
    findContours(canny_output, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));

    /// Find the rotated rectangles and ellipses for each contour
    vector<RotatedRect> minRect(contours.size());
    vector<RotatedRect> minEllipse(contours.size());

    for (int i = 0; i < contours.size(); i++)
    {
        minRect[i] = minAreaRect(Mat(contours[i]));
        if (contours[i].size() > 5)
        {
            minEllipse[i] = fitEllipse(Mat(contours[i]));
        }
    }

    /// Draw contours + rotated rects + ellipses
    Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
    for (int i = 0; i< contours.size(); i++)
    {
        // contour
        drawContours(drawing, contours, i, Scalar(255, 255, 0), 2, 8, vector<Vec4i>(), 0, Point());
        // ellipse
        ellipse(drawing, minEllipse[i], Scalar(0, 0, 255), 2, 8);
        // rotated rectangle
        Point2f rect_points[4]; minRect[i].points(rect_points);
        for (int j = 0; j < 4; j++)
            line(drawing, rect_points[j], rect_points[(j + 1) % 4], Scalar(0, 255, 0), 2, 8);
    }

    /// Show in a window
    namedWindow(canny_window, CV_WINDOW_AUTOSIZE);
    namedWindow(contour_window, CV_WINDOW_AUTOSIZE);

    imshow(canny_window, canny_output);
    imshow(contour_window, drawing);

    waitKey(0);
    return(0);
}
genpfault
  • 51,148
  • 11
  • 85
  • 139
massakrienen
  • 266
  • 2
  • 3
  • 14
  • Since background is same you could try using Background Subtraction methods! http://docs.opencv.org/master/d1/dc5/tutorial_background_subtraction.html – Balaji R Jul 09 '15 at 09:41
  • @BalajiR I tried but couldn't make it work for images. So I asked another question regarding this, here: http://stackoverflow.com/questions/31369757/how-to-use-backgroundsubtractormog2-for-images – massakrienen Jul 12 '15 at 16:04

0 Answers0