Ask Your Question

Revision history [back]

Depending on how accurcate you need it to be, I could give you this code snippet.

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Read the image
    Mat image = imread("/home/spu/Desktop/test.jpg");
    Mat grayscale;
    cvtColor(image, grayscale, COLOR_BGR2GRAY);

    // Threshold the image
    // Since the edge is always black, lets use this to our advantage
    Mat mask;
    threshold(grayscale, mask, 0, 255, CV_8UC1);

    // Find the largest contour in the mask
    // Then find the center of gravity of all the points
    // If this is accurate enough it will be very close near the center
    vector< vector<Point> > contours;
    findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(mask, contours, -1, 255, 2);

    // Loop over contours and find the largest ones based on the area
    // This will ensure that small artefacts do not break this down
    vector<Point> largest_contour = contours[0];
    for(size_t i=0; i<contours.size(); i++){
        if(contourArea(contours[i]) > contourArea(largest_contour)){
            largest_contour = contours[i];
        }
    }

    // Now find the minimum enclosing circle
    Point2f center;
    float radius;
    minEnclosingCircle(largest_contour, center, radius);

    // Draw the centerpoint on the original image
    circle(image, center, 2, Scalar(0,0,255), -1);
    circle(image, center, 10, Scalar(0,255,0), 2);
    stringstream temp;
    temp << "the radius = " << radius << " /" << " the center = " << center;
    putText(image, temp.str(), Point(50,50), FONT_HERSHEY_COMPLEX, 1, Scalar(0,255,0));
    imshow("result", image); waitKey(0);

    return 0;
}

which will result in the following image

image description

Depending on how accurcate you need it to be, I could give you this code snippet.

#include <iostream>
#include <opencv2/opencv.hpp>

using namespace std;
using namespace cv;

int main()
{
    // Read the image
    Mat image = imread("/home/spu/Desktop/test.jpg");
    Mat grayscale;
    cvtColor(image, grayscale, COLOR_BGR2GRAY);

    // Threshold the image
    // Since the edge is always black, lets use this to our advantage
    Mat mask;
    threshold(grayscale, mask, 0, 255, CV_8UC1);

    // Find the largest contour in the mask
    // Then find the center of gravity of all the points
    // If this is accurate enough it will be very close near the center
    vector< vector<Point> > contours;
    findContours(mask, contours, RETR_EXTERNAL, CHAIN_APPROX_NONE);
    drawContours(mask, contours, -1, 255, 2);

    // Loop over contours and find the largest ones based on the area
    // This will ensure that small artefacts do not break this down
    vector<Point> largest_contour = contours[0];
    for(size_t i=0; i<contours.size(); i++){
        if(contourArea(contours[i]) > contourArea(largest_contour)){
            largest_contour = contours[i];
        }
    }

    // Now find the minimum enclosing circle
    Point2f center;
    float radius;
    minEnclosingCircle(largest_contour, center, radius);

    // Draw the centerpoint on the original image
    circle(image, center, 2, Scalar(0,0,255), -1);
    circle(image, center, 10, Scalar(0,255,0), 2);
    stringstream temp;
    temp << "the radius = " << radius << " /" << " the center = " << center;
    putText(image, temp.str(), Point(50,50), FONT_HERSHEY_COMPLEX, 1, Scalar(0,255,0));
    imshow("result", image); waitKey(0);

    return 0;
}

which will result in the following image

image description

But actually I am pretty convinced that if you would just take the following pseudo code, that the end result might even be better

Point center (image.cols/2, image.rows/2);
float radius = image.rows/2;

Because most of those cameras return you a square video with the fisheye result exactly in the middle.