2016-10-19 5 views
0

안녕하세요. 균열 감지 코드가 있지만 코드를 실행하는 동안 오류가 발생했습니다. 여기에 코드가 있습니다. 오류는 2.0f와 2.0에 있습니다. 이 모든 관련 오류가 해결되었지만 새로운 오류 인 DrawMarker는 으로 선언되었습니다. 여기 opencv를 사용한 균열 감지

#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(contours[i]); //analize potential cracks 
    if (crackStats[i].axisMax < minLenght)  //ignore short contours 
     continue; 
    drawContours(src, contours, i, CL_RED, 1); //longer contours are cracks 
    if (crackStats[i].axisMax > maxLenght)  // get longest crack 
     biggest = i; 
} 
// DRAW AROUND BIGGER CRACKS 
if (biggest > 0) { 
    cout << "Cracks Found! Biggest size: " << crackStats[biggest].axisMax << 
     "px (" << 100 * crackStats[biggest].axisMax/theBiscuit.axisMax << "%)" 
     << endl; 
    RotatedRect rr = crackStats[biggest].rr; 
    Point2f rect_points[4]; 
    rr.points(rect_points); 
    //draw enclosing rectangle 
    for (int j = 0; j < 4; j++) 
     line(src, rect_points[j], rect_points[(j + 1) % 4], CL_RED, 1, 8); 
    //draw major axis 
    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; 
    double axis1 = norm(pt0 - pt1); 
    double axis2 = norm(pt2 - pt3); 
    if (axis1>axis2) 
     line(src, pt0, pt1, CL_BLACK, 2); 
    else 
     line(src, pt2, pt3, CL_BLACK, 2); 
} 
imshow("Src", src); 
waitKey(0); 
return 0; 
} 
void Morph(const cv::Mat &src, cv::Mat &dst, int operation,int kernel_type, int size) 
{ 
cv::Point anchor = cv::Point(size, size); 
cv::Mat element = getStructuringElement(kernel_type, cv::Size(2 * size + 1, 2 * size + 1), anchor); 
morphologyEx(src, dst, operation, element, anchor); 
} 

내 이미지 여기에 비스킷의 파일 .....

enter image description here

수정 된 코드의 출력

enter image description here

답변

0

사용중인 수 있음 opencv 이전 버전은 drawMarker을 지원하지 않습니다. Opencv 3.1은 그것을 받아 들인다 click

나는 약간의 변화를 만들었지 만 지금은 효과가있다. 확인해주세요.

#include "opencv/cv.h" 
#include "opencv/highgui.h" 
#include "opencv/cxcore.h" 


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("D:/bis.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; 
    }*/ 

    //taking largest contour 
    int maxx = 0; 
    int maxxIndx = -1; 

    for(int i=0;i<contours.size();i++) 
    { 
     cout<<contours[i].size()<<endl; 

     if(maxx < contours[i].size()) 
     { 
      maxx = contours[i].size(); 
      maxxIndx = i; 
     } 

    } 

    if(maxxIndx==-1) 
    { 
     cerr << "ERROR: invalid mask for the biscuit!"; 
     return 1; 
    } 

    vector<Point> biscuitContour(contours[maxxIndx]); 
    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(contours[i]); //analize potential cracks 
     if (crackStats[i].axisMax < minLenght)  //ignore short contours 
      continue; 
     drawContours(src, contours, i, CL_RED, 1); //longer contours are cracks 
     if (crackStats[i].axisMax > maxLenght)  // get longest crack 
      biggest = i; 
    } 
    // DRAW AROUND BIGGER CRACKS 
    if (biggest > 0) 
    { 
     cout << "Cracks Found! Biggest size: " << crackStats[biggest].axisMax << 
      "px (" << 100 * crackStats[biggest].axisMax/theBiscuit.axisMax << "%)" 
      << endl; 
     RotatedRect rr = crackStats[biggest].rr; 
     Point2f rect_points[4]; 
     rr.points(rect_points); 
     //draw enclosing rectangle 
     for (int j = 0; j < 4; j++) 
      line(src, rect_points[j], rect_points[(j + 1) % 4], CL_RED, 1, 8); 

     for (int j = 0; j < 4; j++) 
     { 
      rect_points[j].x = rect_points[j].x/2.0; 
      rect_points[j].y = rect_points[j].x/2.0; 
     } 
     //draw major axis 
     Point2f pt0 = (rect_points[0] + rect_points[3]); 
     Point2f pt1 = (rect_points[1] + rect_points[2]); 
     Point2f pt2 = (rect_points[0] + rect_points[1]); 
     Point2f pt3 = (rect_points[2] + rect_points[3]); 

     double axis1 = norm(pt0 - pt1); 
     double axis2 = norm(pt2 - pt3); 
     if (axis1>axis2) 
      line(src, pt0, pt1, CL_BLACK, 2); 
     else 
      line(src, pt2, pt3, CL_BLACK, 2); 
    } 

    imshow("Src", src); 
    waitKey(0); 
    return 0; 
} 


void Morph(const cv::Mat &src, cv::Mat &dst, int operation,int kernel_type, int size) 
{ 
cv::Point anchor = cv::Point(size, size); 
cv::Mat element = getStructuringElement(kernel_type, cv::Size(2 * size + 1, 2 * size + 1), anchor); 
morphologyEx(src, dst, operation, element, anchor); 
} 
+1

예 코드가 정상적으로 작동합니다. –

+0

균열이 가장 큰 크기를 발견했습니다! 작동하지 않습니다 –

+0

당신은 예상 출력 이미지를 업로드 할 수 있습니까? –

관련 문제