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.
For this one, a value of 141 works pretty good.
I couldn't find any values for this one, since its color is almost same as the background's.
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);
}