Как я могу получить цветную гистограмму внутри круга на изображении или распределение градиента в круге?

Я обнаружил круглые объекты на изображении с помощью 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);}

Входное изображение хорошо обнаруженного круга
Входное изображение 1

Вывод правильный
Правильный черный круг

Второе изображение с большим количеством кругов
сложное изображение с разными кругами цвета

Вывод неправильный, неправильно обнаружен круг
Неправильно обнаруженный круг

Любая помощь?

3

Решение

Задача ещё не решена.

Другие решения

Других решений пока нет …