Ask Your Question
1

crack detect red line opencv

asked 2016-09-14 00:57:33 -0600

@boom gravatar image

updated 2020-10-23 08:58:00 -0600

i want to make a decision making process of detection of biscuit crack so i used the hough transform for detection of crack. here is the code. It means counting the red pixels,if present then say as crack and if not present say no crack simply. One more thing i want to measure the size of my biscuit.

Mat src = imread("/home/pi/Desktop/pics/grey.jpg");

Mat dst, cdst,pic;


 Canny(src, dst, 30, 160, 3);
cvtColor(dst, pic, CV_GRAY2BGR);
imwrite("/home/pi/Desktop/pics/bisgry.jpg",pic);
// imshow("source",pic);
cdst=~pic;


vector<Vec2f> lines;
HoughLines(dst, lines, 1, CV_PI/180,33 ,1, 1 );

for( size_t i = 0; i < lines.size(); i++ )
{
float rho = lines[i][0], theta = lines[i][1];
Point pt1, pt2;
double a = cos(theta), b = sin(theta);
double x0 = a*rho, y0 = b*rho;
pt1.x = cvRound(x0 + 1000*(-b));
pt1.y = cvRound(y0 + 1000*(a));
pt2.x = cvRound(x0 - 1000*(-b));
pt2.y = cvRound(y0 - 1000*(a));
line( cdst, pt1, pt2, Scalar(0,0,255), 3, CV_AA);
}

  /*vector<Vec4i> lines;
  HoughLinesP(dst, lines, 1, CV_PI/180, 50, 50, 10 );
  for( size_t i = 0; i < lines.size(); i++ )
  {
  Vec4i l = lines[i];
   line( cdst, Point(l[0], l[1]), Point(l[2], l[3]), Scalar(0,0,255), 3, CV_AA);
   }*/

 [enter image description here][1] imshow("source", src);
 imshow("source1",pic);
imshow("detected lines", cdst);
imwrite("/home/pi/Desktop/pics/cracked.jpg",cdst);

waitKey(); image description image description

@pklab there are the error sir i added headers imgproc.h,highgui.h,opencv2.h

pi@raspberrypi:~/Desktop $ g++ -ggdb `pkg-config --cflags --libs opencv` blob.cpp -o bolb

Ok i again run the code by including namespace cv and std but these are the errors. please give me some hints so that i can improve. i am learner and student not professional sir.

    alarray<_Tp>’
     Point2f pt1 = (rect_points[1] + rect_points[2]) / 2.0;
                                                       ^
      In file included from /usr/include/opencv2/contrib/retina.hpp:76:0,
             from /usr/include/opencv2/contrib/contrib.hpp:979,
             from /usr/local/include/opencv2/opencv.hpp:59,
             from crackb.cpp:5:
             /usr/include/c++/4.9/valarray:1170:1: note:   template argument deduction/substitution failed:
               crackb.cpp:118:59: note:   mismatched types ‘const std::valarray<_Tp>’ and ‘double’
               Point2f pt1 = (rect_points[1] + rect_points[2]) / 2.0;
               file included from /usr/local/include/opencv2/core/core.hpp:4884:0,
             from /usr/local/include/opencv2/highgui/highgui.hpp:46,
             from crackb.cpp:2:
              /usr/local/include/opencv2/core/mat.hpp:1301:20: note: cv::MatExpr cv::operator/(const                                  
              CV_EXPORTS MatExpr operator / (const MatExpr& e1, const MatExpr& e2);
                ^
              /usr/local/include/opencv2/core/mat.hpp:1301:20: note:   no known conversion for argument 1 from              ‘cv::Point_<float>’ to ‘const cv::MatExpr&’
          /usr/local/include/opencv2/core/mat.hpp:1300:20: note: cv::MatExpr cv::operator/(double, const    cv::MatExpr&)
              CV_EXPORTS MatExpr operator / (double s, const MatExpr& e);
                ^
             /usr/local/include/opencv2/core/mat.hpp:1300:20: note:   no known conversion for argument 1 from ‘cv::Point_<float ...
(more)
edit retag flag offensive close merge delete

Comments

since your idea is based on finding one or more hough lines, you can simply check lines.size().

there is no need to count red pixels at all.

berak gravatar imageberak ( 2016-09-14 01:14:36 -0600 )edit
1

what if crack is an arc ? I would not use hough but simpler blob detection or contours with stats... for biscuit size too. I suggest post original image better if color.

pklab gravatar imagepklab ( 2016-09-14 02:01:39 -0600 )edit

@berak line.size().i didn't find any function in opencv and how to use it

@boom gravatar image@boom ( 2016-09-14 04:32:02 -0600 )edit

@pklab i edit the original image i don't bother about corner crack

@boom gravatar image@boom ( 2016-09-14 04:32:46 -0600 )edit
2

@gauravsharma01901 : maybe it's a good idea, to leave all this aside for a few days, and rather try to get basic c++ skills in the meantime. if you don't know, how to handle a vector, -- what on earth are you doing here, then ?

berak gravatar imageberak ( 2016-09-16 00:38:23 -0600 )edit

@berak dear berak i don't know why my compiler not reading vector<> i have example code of opencv also have vector. i also shows the errors. i have done with it but nothing happens

include<vector>

@boom gravatar image@boom ( 2016-09-16 01:14:41 -0600 )edit

@gauravsharma01901 if you don't know how to use vector<> there is nothing we can do here...bye bye

pklab gravatar imagepklab ( 2016-09-16 01:45:33 -0600 )edit

2 answers

Sort by » oldest newest most voted
3

answered 2016-09-15 13:57:49 -0600

pklab gravatar image

updated 2016-09-16 11:32:44 -0600

As I said, I would not use hough but simpler blob detection or contours with stats. Below is my implementation, this is my result:

Console output

BISCUIT STATS:
    Area [px^2]: 12386
    Axis[px]: 125.292/126.988
    Axis Ratio: 0.986644
    Circularity: 0.870751
    Abs(eccentricity): 0.621218
Cracks Found! Biggest size: 100.896px (79.4533%)

Internal processing

Interal Blobs

Result

Result

The code (maybe I'll come back with some explains) EDIT: Added few missing code

#include <opencv2\opencv.hpp>
using namespace std;
using namespace cv;
#define CL_GREEN  Scalar(0  , 255, 0  )
#define CL_RED    Scalar(0  , 0  , 255)
#define CL_BLU    Scalar(255, 0  , 0  )
#define CL_BLACK  Scalar(0  , 0  , 0  )
void Morph(const cv::Mat &src, cv::Mat &dst, int operation = cv::MORPH_OPEN, 
           int kernel_type = cv::MORPH_RECT, int size = 1);
struct contourStats{
    double area, perimeter, axisMin, axisMax, axisAvg, eccentricity, axisRatio, circularity;
    Point2d center;
    RotatedRect rr;
    contourStats(){}
    contourStats(const vector<Point> &contour)
    {
        calculateStats(contour);
    }
    void calculateStats(const vector<Point> &contour)
    {
        Moments m = cv::moments(contour, true);
        area = m.m00;
        center = Point2f(-1, -1);
        if (area > 0){
            center.x = cvRound(m.m10 / m.m00);
            center.y = cvRound(m.m01 / m.m00);
        }
        eccentricity = DBL_MAX;
        if ((m.m20 + m.m02) > 0)
            eccentricity = (pow((m.m20 - m.m02), 2) - 4 * m.m11 * m.m11) / pow((m.m20 + m.m02), 2);
        // axis ratio:circles have ratio=1 lines have ratio->0
        rr = minAreaRect(contour);
        axisMin = min(rr.size.height, rr.size.width);
        axisMax = max(rr.size.height, rr.size.width);
        axisAvg = (axisMin+axisMax) / 2.0;
        axisRatio = axisMax > 0 ? axisMin / axisMax : 0;
        perimeter = arcLength(contour, false);
        circularity = perimeter > 0 ? 4 * CV_PI * area / pow(perimeter, 2) : 0;
    }
    void printStats(const string &title)
    {
        cout << endl << title << endl
            << "\tArea [px^2]: " << area << endl
            << "\tAxis[px]: " << axisMin << "/" << axisMax << endl
            << "\tAxis Ratio: " << axisRatio << endl
            << "\tCircularity: " << circularity << endl
            << "\tAbs(eccentricity): " << abs(eccentricity) << endl;
    }
};

int main(int argc, char** argv)
{
    Mat src, gray, edges, cracks,tmp;
    Mat biscuitMask;
    //src = imread("../img/biscotto_rotated.jpg");
    src = imread("../img/biscotto.jpg");
    cvtColor(src, gray, CV_BGR2GRAY);
    // GET ALL EDGES (CRACKS AND BISCUIT)
    Canny(gray, edges, 100, 200, 3);
    Morph(edges, edges, MORPH_CLOSE, MORPH_ELLIPSE, 5);
    // GET THE BISCUIT ONLY
    GaussianBlur(gray, gray, Size(7, 7), 0);
    threshold(gray, biscuitMask, 0, 255, THRESH_OTSU);
    // VALIDATE THE BISCUIT
    vector<vector<Point> > contours;
    biscuitMask.copyTo(tmp);
    findContours(tmp, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
    if ((contours.size() > 1) || (contours[0].size() < 6)) {
        cerr << "ERROR: invalid mask for the biscuit!";
        return 1;
    }
    vector<Point> biscuitContour(contours[0]);
    contourStats theBiscuit(biscuitContour);
    theBiscuit.printStats("BISCUIT STATS:");
    if (theBiscuit.circularity < 0.85) {
        cout << "WARNING: invalid biscuit circularity!";
    }
    drawMarker(src, theBiscuit.center, CL_BLU, MARKER_CROSS, theBiscuit.axisAvg / 8);
    circle(src, theBiscuit.center, theBiscuit.axisAvg / 2, CL_BLU, 2);
    //polylines(src, biscuitContour, true, CL_GREEN); 

    // GET ONLY THE CRACKS INSIDE THE BISCUIT
    Morph(biscuitMask, biscuitMask, MORPH_ERODE,MORPH_ELLIPSE, 5);
    cracks = (edges & biscuitMask);
    imshow("cracks", cracks);

    findContours(cracks, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);

    double minLenght = theBiscuit.axisAvg / 2;
    double maxLenght = 0;
    int biggest = -1;
    vector<contourStats> crackStats(contours.size());
    for (size_t i = 0; i < contours.size(); i++)
    {
        drawContours(src, contours, i, CL_GREEN, 1); //all contours in GREEN
        crackStats[i].calculateStats ...
(more)
edit flag offensive delete link more

Comments

Added missed Morph function. PLEASE STOP TO POST TONS OF COMPILER ERRORS and start with debug and investigation.

Finally maybe you have an old version of OpenCV. My code compiles fine with OpenCV 3.1.0. See here how to update OpenCV on Raspberry

pklab gravatar imagepklab ( 2016-09-16 11:40:40 -0600 )edit

Ok sir thanks for your kind help......i will investigate it if error occurs i will ask you also updating my opencv

@boom gravatar image@boom ( 2016-09-18 23:03:17 -0600 )edit

@pklab i update the opencv but still same things.this time not error but some NOTE like /usr/include/c++/valarray :note template class........something like this . am i compiling it right as g++ -ggbd 'pkg-config' --cflags --libs opencv' <filename> -o object and point2f pt3 =(rect_points[2] +rect_points[3] /2.0); is common in every line

@boom gravatar image@boom ( 2016-09-20 00:36:26 -0600 )edit

You should know that these are warnings for implicit conversions that may alter a value . You might disable the warnings on your compiler or you can solve the warning using explicit cast where needed e.g. 2.0f is a float, while 2.0 is a double.

pklab gravatar imagepklab ( 2016-09-21 03:36:27 -0600 )edit

hello sir, i investigate the code and yeah!! it shows me one error now as drawMarker was not declare in this scope, i added highgui.hpp and imgproc.hpp as weel but it shows the error. When i remove 2.0 from this then i got no error except this drawmarker Point2f pt0 = (rect_points[0] + rect_points[3]) / 2.0; Point2f pt1 = (rect_points[1] + rect_points[2]) / 2.0; Point2f pt2 = (rect_points[0] + rect_points[1]) / 2.0; Point2f pt3 = (rect_points[2] + rect_points[3]) / 2.0;

@boom gravatar image@boom ( 2016-10-17 05:01:25 -0600 )edit

@gauravsharma01901 It looks you are using an old version of OpenCV because

  1. check the docdrawMarker is available in 3.1.0 and defined in Image processing module, btw it just draws a cross !
  2. About Point operators, the case pt1 = pt2 / a; is available in 3.0.0 but isn't available in 2.4.12.

try with

Point2f pt0 = (rect_points[0] + rect_points[3]) * 0.5f;

or more flat

Point2f pt0;
pt0.x = (rect_points[0].x + rect_points[3].x) / 2.0f;
pt0.y = (rect_points[0].y + rect_points[3].y) / 2.0f;
pklab gravatar imagepklab ( 2016-10-19 12:29:43 -0600 )edit

@pklab Thanks It worked fine after editing and debugging. I will oblige you if give me some small hint of this code mean Algorithms used in it or something like this.

@boom gravatar image@boom ( 2016-11-10 23:50:17 -0600 )edit

Commented code should help, BTW:

  • The structure contourStats provides some useful stats on contour.
  • Get all edges (cracks and biscuit) using canny edge detector. Morphology close is used to fill small irregularities.
  • Get a biscuitMask using simple threshold and contours
    • theBiscuit is valid if its contour has valid size and circularity
  • Get a mask of cracks inside the biscuit using logical AND between eroded biscuitMask and all edges mask
  • Find contours of all cracks (and small holes)
    • Analyze potential cracks using basic info like axisMax
    • Draw an ellipse around the biggest crack (if any exist)
pklab gravatar imagepklab ( 2016-11-13 12:01:44 -0600 )edit
0

answered 2016-09-14 14:30:31 -0600

I recommend using Probabilistic Hough Transform - void HoughLinesP(InputArray image, OutputArray lines, double rho, double theta, int threshold, double minLineLength=0, double maxLineGap=0 )

vector<Vec2f> lines;
HoughLinesP(dst, lines, 1, CV_PI/180,33 ,1, 1 );

Now, lines contains the end points of the line segments detected by the Probabilistic Hough transform. If you want to know the length of the line segment (in pixels), you can calculate the distance between its end points.

What berak means to say is that since cracks are detected as lines by Hough Transform, if you get lines.size() = 0 (i.e. the lines vector is empty), no cracks were found.

edit flag offensive delete link more

Comments

@v4ven27 thanks sir But i want to know how to use lines.size() simply. i don't know how to use it because i m new in opencv

@boom gravatar image@boom ( 2016-09-14 23:08:01 -0600 )edit

@pklab Thanks very much i am really oblige you. Ok i will implement it if any problem occurs i will ask you.

@boom gravatar image@boom ( 2016-09-15 23:04:04 -0600 )edit

@pklab it shows error in Morph. morph was not declared in this scope

@boom gravatar image@boom ( 2016-09-16 05:38:40 -0600 )edit

@gauravsharma01901 please! try to post comments under the related answer

pklab gravatar imagepklab ( 2016-09-16 11:10:06 -0600 )edit

@gauravsharma01901 Please, again and again! try to post comments under the related answer.

pklab gravatar imagepklab ( 2016-10-07 03:51:57 -0600 )edit

Question Tools

1 follower

Stats

Asked: 2016-09-14 00:57:33 -0600

Seen: 6,637 times

Last updated: Sep 16 '16