如何计算OpenCV中椭圆的偏心率?

时间:2016-05-24 09:37:10

标签: c++ opencv image-processing contour

我目前正在进行一个图像处理项目,我被困在一个部分而且无法继续前进。

我想用Visual Studio和C ++语言计算我在OpenCV中绘制的椭圆的偏心率,但我不确定如何做到这一点。要计算偏心率,我需要半长轴和半短轴的值,但是,我不确定如何得到这些值。

我也想过寻找循环而不是偏心,但我不确定这是不是一个可行的选择。

请问我对此有何建议?有没有办法在OpenCV中实现代码来查找在对象上自动绘制的椭圆的偏心率?

谢谢。

我的代码如下:

#include "opencv2\imgproc\imgproc.hpp"
#include "opencv2\highgui\highgui.hpp"
#include "opencv2\photo\photo.hpp"
#include "highgui.h"
#include <cv.h>
#include <iostream>
#include <stdlib.h>
#include <stdio.h>

using namespace cv;
using namespace std;

int main( int argc, char** argv ){

    //Declarations
    //double alpha; /**< Simple contrast control */ //unused
    //int beta;  /**< Simple brightness control */ //unused
    float minVal;
    float maxVal; 
    Mat bw_img;
    Mat contrast1;
    Mat gaussian_img;
    Mat filtered_img;
    Mat weighted_img;
    Mat adaptive_img;

    //Loads image from file and put image matrix into "original_photo"
    Mat original_img = imread ("crack3.jpg", 1);

    //Convert color-to-gray image
    cvtColor( original_img, bw_img, CV_BGR2GRAY );
    imshow("bw_img", bw_img);

    //Gaussian filtering
    int i = 9;
    GaussianBlur(bw_img,gaussian_img,Size(i,i),0,0);
    imshow("gaussian_img", gaussian_img);

    //HPF kernel
    Mat kernel = (Mat_<float>(3,3) << 
        0,  -1, 0,
        -1, 5, -1,
        0,  -1, 0); 

    filter2D(gaussian_img, filtered_img,-1, kernel, Point(-1,-1),0);

    //Extract high-frequency features, e.g. edges  show up.
    addWeighted(filtered_img, 1.5, bw_img, -0.5, 0,weighted_img);
    imshow("weighted_img",weighted_img);

    //Perform adaptive thresholding
    adaptiveThreshold(weighted_img,adaptive_img,255,ADAPTIVE_THRESH_GAUSSIAN_C, THRESH_BINARY, 51, 20);
    imshow("adaptive_img",adaptive_img);

    //Construct structuring element
    Mat struc_elem = getStructuringElement(MORPH_RECT,Size(7,7));

    //Perform erosion first
    Mat eroded_img;
    erode(adaptive_img,eroded_img,struc_elem);
    imshow("eroded_img",eroded_img);

    //Perform dilation next
    Mat dilate_img;
    dilate(eroded_img,dilate_img,struc_elem);
    imshow("dilate_img",dilate_img);

    //Round 2: Erode first, Dilate later
    Mat erode2;
    erode(dilate_img,erode2,struc_elem);
    imshow("erode2",erode2);

    //Round 2
    Mat dilate2;
    dilate(erode2,dilate2,struc_elem);
    imshow("dilate2",dilate2);

    //Edge preserving blur
    Mat blur;
    medianBlur(dilate2,blur,7);
    imshow("blur",blur);

    //Round 3: Erode first, Dilate later
    Mat erode3;
    erode(blur,erode3,struc_elem);
    imshow("erode3",erode3);

    //Round 3
    Mat dilate3;
    dilate(erode3,dilate3,struc_elem);
    imshow("dilate3",dilate3);

    /*double otsu_thresh_val = threshold(dilate_img, dilate_img, 0, 255, CV_THRESH_BINARY | CV_THRESH_OTSU);
    double high_thresh_val  = otsu_thresh_val,lower_thresh_val = otsu_thresh_val * 0.5;

    Mat cannyOP;
    Canny( dilate3, cannyOP, lower_thresh_val, high_thresh_val );
    imshow("cannyOP",cannyOP);*/

    //Find contours first.
    vector<vector<Point>> contours; // Vector for storing contour
    vector<Vec4i> hierarchy;
    dilate3 = 255 - dilate3; //invert image to avoid drawing the contours on image border if the object is very close to image border
    findContours(dilate3,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE);

    //Draw contours (Preparation phase)
    // Find the ellipses for each contour
    vector<RotatedRect> minRect( contours.size() );
    vector<RotatedRect> minEllipse( contours.size() );
    for( size_t i = 0; i < contours.size(); i++ ){
        minRect[i] = minAreaRect( Mat(contours[i]));
        if( contours[i].size() > 5){
            minEllipse[i] = fitEllipse( Mat(contours[i]) );
        }
    }

    //Now draw the ellipses, like, seriously draw them.
    Mat drawing = Mat::zeros( dilate3.size(), CV_8UC3 );
    for( int i = 0; i< contours.size(); i++ )
    {
        Scalar color = Scalar(255, 125, 255);
       // contour
       drawContours( drawing, contours, i, color, 1, 8, hierarchy );
       // ellipse
       Scalar color2 = Scalar(32, 125, 166);
       ellipse( drawing, minEllipse[i], color2, 1, 8 );
       //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], color, 1, 8 );
    }
    imshow("drawing",drawing);

    //Find area of the circle


    //wait for long long time
    int c = waitKey(20000000000000);

    //if you get impatient, return
    if (c == 27)
    {
    return 0;
    }
}
  • 我的输出图片如下:

Output image after compiling the above code

0 个答案:

没有答案