Я обнаружил круглые объекты на изображении с помощью OpenCV и C ++ и с помощью функции houghcircle. Но я бы хотел отфильтровать только те круги, которые имеют темный цвет (это должно быть окно двери самолета). Поэтому я решил использовать цветовую гистограмму внутри обнаруженного круга на изображении или распределение градиента в этих кругах для фильтрации. Это работает на некоторых изображениях, как на представленном изображении. Но когда на изображении больше кругов, темного круга не найти. Также я играл с хитрым порогом, но хотелось бы, чтобы это происходило автоматически. Так в принципе, как сделать программу более надежной?
Во-первых, вот код на C ++ с использованием OpenCV и C ++
#include "opencv2/highgui/highgui.hpp"#include "opencv2/imgproc/imgproc.hpp"#include <iostream>
#include <stdio.h>
using namespace cv;
using namespace std;
#include <vector>
int thresh = 200;
int max_thresh = 400;
Mat src;
void thresh_callback(int, void* );
int main()
{
cv::Mat src = cv::imread("d4.png");
resize(src, src, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window = "Source";
namedWindow( source_window, CV_WINDOW_AUTOSIZE );
imshow( source_window, src );
createTrackbar( " Canny thresh:", "Source", &thresh, max_thresh, thresh_callback );
thresh_callback( 0, 0 );waitKey(0);
return(0);
}
void thresh_callback(int, void* ) {
Mat src_gray;
cv::Mat bgr_image = cv::imread( "d4.png");
cv::Mat orig_image = bgr_image.clone();
cvtColor( bgr_image, src_gray, COLOR_BGR2HSV );
medianBlur(src_gray, src_gray, 3);
Mat canny_output;
Canny( src_gray, canny_output, thresh, thresh*3.5, 3 );
// Threshold the HSV image, keep only the black pixels
cv::Mat lower_black_hue_range;
cv::Mat upper_black_hue_range;
cv::inRange(canny_output, cv::Scalar(0, 0, 0), cv::Scalar(10, 10, 40), lower_black_hue_range);
cv::inRange(canny_output, cv::Scalar(0,0, 41), cv::Scalar(10, 15, 50), upper_black_hue_range);
// Combine the above two images
cv::Mat black_hue_image;
cv::addWeighted(lower_black_hue_range, 1.0, upper_black_hue_range, 1.0, 0.0, black_hue_image);
cv::GaussianBlur(black_hue_image, black_hue_image, cv::Size(9, 9), 2, 2);
// Use the Hough transform to detect circles in the combined threshold image
std::vector<cv::Vec3f> circles;
cv::HoughCircles(black_hue_image, circles, CV_HOUGH_GRADIENT, 1, black_hue_image.rows/1, 10, 100, 10, 0);
// Loop over all detected circles and outline them on the original image
if(circles.size() == 0) std::exit(-1);
for(size_t current_circle = 0; current_circle < circles.size(); ++current_circle) {
Point center(cvRound(circles[current_circle][0]), cvRound(circles[current_circle][1]));
int radius = cvRound(circles[current_circle][2]);
cv::circle(orig_image, center, radius, cv::Scalar(0, 255, 0), 5);
}
// Show images
resize(lower_black_hue_range, lower_black_hue_range, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window1 = "Threshold lower image";
namedWindow( source_window1, CV_WINDOW_AUTOSIZE );
imshow( source_window1, lower_black_hue_range );
//cv::namedWindow("Threshold lower image", cv::INTER_CUBIC);
//cv::imshow("Threshold lower image", lower_black_hue_range);
resize(upper_black_hue_range, upper_black_hue_range, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window2 = "Threshold upper image";
namedWindow( source_window2, CV_WINDOW_AUTOSIZE );
imshow( source_window2, lower_black_hue_range );
//cv::namedWindow("Threshold upper image", cv::INTER_CUBIC);
//cv::imshow("Threshold upper image", upper_black_hue_range);
resize(black_hue_image, black_hue_image, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window3 = "Combined threshold images";
namedWindow( source_window3, CV_WINDOW_AUTOSIZE );
imshow( source_window3, black_hue_image );
//cv::namedWindow("Combined threshold images", cv::INTER_CUBIC);
//cv::imshow("Combined threshold images", black_hue_image);
resize(orig_image, orig_image, Size(640,480), 0, 0, INTER_CUBIC);
char* source_window4 = "Detected black circles on the input image";
namedWindow( source_window4, CV_WINDOW_AUTOSIZE );
imshow( source_window4, orig_image );
//cv::namedWindow("Detected black circles on the input image", cv::INTER_CUBIC);
//cv::imshow("Detected black circles on the input image", orig_image);}
Входное изображение хорошо обнаруженного круга
Второе изображение с большим количеством кругов
Вывод неправильный, неправильно обнаружен круг
Любая помощь?
Задача ещё не решена.
Других решений пока нет …