/
RDA
/
STZ
Обзор
Документация
Войти
/
RDA
/
STZ
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
lab7/lab7_3_circle_detect.cpp
150 строк
5 KB
daniil rybyakov
1
11 мар 2025, 17:55
11 мар 2025, 17:55
04282df
Код
Авторство
О чём код?
#include <iostream> #include <opencv2/opencv.hpp> #include <vector> void showHistogram(const cv::Mat& hist, const std::string& windowName) // отображение гистограммы { int hist_w = 512, hist_h = 400; int bin_w = cvRound((double)hist_w / 256); cv::Mat histImage(hist_h, hist_w, CV_8UC3, cv::Scalar(0, 0, 0)); cv::normalize(hist, hist, 0, histImage.rows, cv::NORM_MINMAX); // соединение линий for (int i = 1; i < 256; i++) line(histImage, cv::Point(bin_w * (i - 1), hist_h - cvRound(hist.at<float>(i - 1))), cv::Point(bin_w * (i), hist_h - cvRound(hist.at<float>(i))), cv::Scalar(255, 255, 255), 2, 8, 0); cv::imshow(windowName, histImage); } void BalanceBGR(cv::Mat& img, double b, double g, double r) // корректировка яркости каналов { std::vector<cv::Mat> channels; split(img, channels); channels[0] *= b; channels[1] *= g; channels[2] *= r; merge(channels, img); } void BGR2BIN(const cv::Mat& src, cv::Mat& dst, double thresh) // цыетное в бинаризованное { cv::Mat gray; cvtColor(src, gray, cv::COLOR_BGR2GRAY); threshold(gray, dst, thresh, 255, cv::THRESH_BINARY_INV); } std::vector<cv::Vec3f> detectCircles(const cv::Mat& binaryImg) // поиск кругов { std::vector<cv::Vec3f> circles; HoughCircles(binaryImg, circles, cv::HOUGH_GRADIENT, 2, 30, 100, 100, 5, 0); return circles; } cv::Mat img_to_colourhist(const cv::Mat& img) //вычисление нормированной гистограммы { cv::Mat hsv; cvtColor(img, hsv, cv::COLOR_BGR2HSV); std::vector<cv::Mat> hsv_planes; split(hsv, hsv_planes); int histSize = 256; float range[] = {0, 256}; //диапазон значений, которые могут принимать пиксели const float* histRange = {range}; cv::Mat hist; calcHist(&hsv_planes[0], 1, 0, cv::Mat(), hist, 1, &histSize, &histRange, true, false); normalize(hist, hist, 0, 1, cv::NORM_MINMAX); return hist; } std::string determineMaterial(const cv::Mat& img, cv::Vec3f circle, const cv::Mat& histNikel, const cv::Mat& histCopper) // определение материала на основе сравнения гистограмм { int x = round(circle[0]); int y = round(circle[1]); int r = round(circle[2]); cv::Mat roi = img(cv::Rect(x-r, y-r, 2*r, 2*r)); cv::Mat histCurrent = img_to_colourhist(roi); // сравнение гистограмм double MatchNikel = compareHist(histCurrent, histNikel, cv::HISTCMP_CORREL); double MatchCopper = compareHist(histCurrent, histCopper, cv::HISTCMP_CORREL); return (MatchNikel > MatchCopper) ? "Nickel" : "Cooper"; } int main() { cv::Mat img_money_src = cv::imread("src/money.png", cv::IMREAD_COLOR); cv::Mat img_nickel = cv::imread("src/nikel.jpg", cv::IMREAD_COLOR); cv::Mat img_copper = cv::imread("src/copper.jpg", cv::IMREAD_COLOR); if (img_money_src.empty() || img_nickel.empty() || img_copper.empty()) { std::cerr << "Img Error" << std::endl; return -1; } // корректировка яркости cv::Mat img_money = img_money_src.clone(); BalanceBGR(img_copper, 0.8, 1, 1); BalanceBGR(img_nickel, 0.9, 0.9, 1); cv::imshow("Original_Filtered", img_money); cv::imshow("Nickel", img_nickel); cv::imshow("Copper", img_copper); // вычисление гистограмм cv::Mat histNikel = img_to_colourhist(img_nickel); cv::Mat histCopper = img_to_colourhist(img_copper); // showHistogram(histNikel, "hist nikel"); // showHistogram(histCopper, "hist copper"); // бинаризация cv::Mat img_money_bin; BGR2BIN(img_money, img_money_bin, 151); // imshow("Bin_img", img_money_bin); // поиск кругов std::vector<cv::Vec3f> circles = detectCircles(img_money_bin); cv::Mat imgResult = img_money_src.clone(); // Окружности для кругов for (auto& c : circles){ cv::Point center(cvRound(c[0]), cvRound(c[1])); int radius = cvRound(c[2]); circle(imgResult, center, radius, cv::Scalar(0, 255, 0), 2); std::string Material = determineMaterial(img_money, c, histNikel, histCopper); cv::Point textPosition(center.x - radius/2, center.y); putText(imgResult, Material, textPosition, cv::FONT_HERSHEY_SIMPLEX, 0.5, cv::Scalar(255, 255, 255), 2); } imshow("res", imgResult); cv::waitKey(0); return 0; }