2017-01-15 12 views
0

enter image description hereOpenCV의

를 사용하여 집의 가장자리를 제거하는 방법 위의 이미지의 원 콘텐츠를 제거하는 방법. enter image description here

+0

제 화상의 직사각형이 폐쇄되지 않고 도스 컨텍스트에서 평균 제거 무엇 허점 –

+0

있다 : 원본 이미지 아래로 보여? 그것은 모두 뒤로 또는 흰색이어야합니까? –

+0

아마도 폐쇄가 도움이 될까요? http://docs.opencv.org/2.4/doc/tutorials/imgproc/opening_closing_hats/opening_closing_hats.html –

답변

0
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <cmath> 
#include <iostream> 
using namespace cv; 
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, 0, 255), CV_FILLED); 
    cv::putText(im, label, pt, fontface, scale, CV_RGB(0, 0, 0), thickness, 8); 
} 

int main() 
{ 
    //cv::Mat src = cv::imread("polygon.png"); 
    Mat src = imread("3.bmp");//2.png 3.jpg 
    Mat src_copy; 
    src.copyTo(src_copy); 
    resize(src, src, cvSize(0, 0), 1, 1); 
    cout << "src type " << src.type() << endl; 
    Mat mask(src.size(), src.type(), Scalar(0)); 
    if (src.empty()) 
     return -1; 

    // Convert to grayscale 
    cv::Mat gray; 
    if (src.type() != CV_8UC1) 
     cv::cvtColor(src, gray, CV_BGR2GRAY); 

    // Use Canny instead of threshold to catch squares with gradient shading 
    cv::Mat bw; 
    cv::Canny(gray, bw, 0, 50, 5); 

    // Find contours 
    std::vector<std::vector<cv::Point> > contours; 
    cv::findContours(bw.clone(), contours, CV_RETR_LIST, CV_CHAIN_APPROX_NONE); 

    drawContours(src, contours, -1, Scalar(0, 255, 0), 2); 
    std::vector<cv::Point> approx; 
    cv::Mat dst = src.clone(); 

    for (int i = 0; i < contours.size(); i++) 
    { 
     // Approximate contour with accuracy proportional 
     // to the contour perimeter 

     cv::approxPolyDP(cv::Mat(contours[i]), approx, cv::arcLength(cv::Mat(contours[i]), true)*0.1, true); 

     // Skip small or non-convex objects 
     if (std::fabs(cv::contourArea(contours[i])) < 500 || !cv::isContourConvex(approx)) 
      continue; 

     if (approx.size() == 3) 
     { 
      //setLabel(dst, "TRI", contours[i]); // Triangles 
     } 
     else if (approx.size() >= 4 && approx.size() <= 6) 
     { 
      // Number of vertices of polygonal curve 
      int vtc = approx.size(); 

      // Get the cosines of all corners 
      std::vector<double> cos; 
      for (int j = 2; j < vtc + 1; j++) 
       cos.push_back(angle(approx[j%vtc], approx[j - 2], approx[j - 1])); 

      // Sort ascending the cosine values 
      std::sort(cos.begin(), cos.end()); 

      // Get the lowest and the highest cosine 
      double mincos = cos.front(); 
      double maxcos = cos.back(); 

      // Use the degrees obtained above and the number of vertices 
      // to determine the shape of the contour 
      if (vtc == 4 && mincos >= -0.2 && maxcos <= 0.5) 
      { 
       Mat element = getStructuringElement(MORPH_RECT, Size(13, 13)); 
       setLabel(dst, "RECT", contours[i]); 
       drawContours(mask, contours, i, Scalar(255, 255, 255), CV_FILLED); 
       dilate(mask, mask, element); 
       src_copy = src_copy - mask; 
      } 

      else if (vtc == 5 && mincos >= -0.34 && maxcos <= -0.27) 
       setLabel(dst, "PENTA", contours[i]); 
      else if (vtc == 6 && mincos >= -0.55 && maxcos <= -0.45) 
       setLabel(dst, "HEXA", contours[i]); 
     } 
     else 
     { 
      // Detect and label circles 
      double area = cv::contourArea(contours[i]); 
      cv::Rect r = cv::boundingRect(contours[i]); 
      int radius = r.width/2; 

      if (std::abs(1 - ((double)r.width/r.height)) <= 0.2 && 
       std::abs(1 - (area/(CV_PI * std::pow(radius, 2)))) <= 0.2) 
       setLabel(dst, "CIR", contours[i]); 
     } 
    } 

    //cv::imshow("src", src); 
    imwrite("mask.jpg", mask); 
    imwrite("src.jpg", src_copy); 
    imwrite("dst.jpg", dst); 
    cv::imshow("dst", dst); 
    cv::waitKey(0); 
    return 0; 
}