背景:需要在image中提取圆孔圆心的位置,用到opencv中的hugh检测的方法,提取的效果还不错。但是只是初步的版本,没有增加更多的鲁棒性判断。
#include <opencv2/imgcodecs.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>
int main(int argc, char** argv)
{
// read a image
std::string file_name = "/home/liuzhiyang/image.png";
cv::Mat input_image = cv::imread(file_name, cv::IMREAD_COLOR);
if (input_image.empty())
{
std::cout << "Error to open image file !" << std::endl;
return 0;
}
// cv::imshow("origin image", input_image);
// undistort image
cv::Mat undistort_image;
float fx = 1.0757955405501191e+03, fy = 1.0762345733674481e+03;
float cx = 9.6249394948422218e+02, cy = 6.1957628038839391e+02;
float k1 = -1.1995613777994101e-01, k2 = 8.6245969435724004e-02, k3 = -2.6778267188218002e-02;
float p1 = 1.0621717082800000e-03, p2 = 5.4033385896265832e-04;
cv::Mat camera_matrix = (cv::Mat_<float>(3, 3) << fx, 0.0, cx, 0.0, fy, cy, 0.0, 0.0, 1.0);
cv::Mat distortion_coeff = (cv::Mat_<float>(1, 5) << k1, k2, p1, p2, k3);
// cv::undistort(input_image, undistort_image, camera_matrix, distortion_coeff);
// cv::imshow("undistortion image", undistort_image);
// // extract roi area
// cv::Mat roi_image = input_image(cv::Rect(0, 0, input_image.cols / 2, input_image.rows / 2));
// cv::imshow("roi image", roi_image);
//extract hough circles
cv::Mat gray_image;
cv::cvtColor(input_image, gray_image, cv::COLOR_BGR2GRAY);
cv::GaussianBlur(gray_image, gray_image, cv::Size(9, 9), 1, 1);
std::vector<cv::Vec3f> circles_pixel(4);
int min_radius = gray_image.rows / 16;
int max_radis = gray_image.rows / 8;
int min_distance = gray_image.rows / 8;
cv::HoughCircles(gray_image, circles_pixel, cv::HOUGH_GRADIENT, 1, min_distance, 200, 100, min_radius, max_radis);
// get normalization plane coordination
std::vector<cv::Vec3f> circles_coor(4);
for (size_t i = 0; i < circles_pixel.size(); ++i)
{
circles_coor[i][0] = (circles_pixel[i][0] - cx) / fx;
circles_coor[i][1] = (circles_pixel[i][1] - cy) / fy;
std::cout << circles_coor[i][0] << " " << circles_coor[i][1] << std::endl;
}
// show circles
for( size_t i = 0; i < circles.size(); i++ )
{
cv::Vec3i c = circles[i];
cv::circle( gray_image, cv::Point(c[0], c[1]), c[2], cv::Scalar(0,0,255), 1, cv::LINE_AA);
cv::circle( gray_image, cv::Point(c[0], c[1]), 2, cv::Scalar(0,255,0), 1, cv::LINE_AA);
}
cv::imshow("detected circles", gray_image);
cv::waitKey(0);
}
-
后记
在使用
cv::HoughCircles()
函数前,高斯模糊的参数、圆孔半径和最小距离设置对提取圆孔的准确性影响还是挺大的。