1 | initial version |
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
2 | No.2 Revision |
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
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.