#c #opencv
#c #opencv
Вопрос:
Я новичок в программировании (изучаю книгу Бьярне С.), начал изучать C и OpenCV. У меня есть проект, над которым нужно работать, поэтому я пропустил много глав, чтобы понять определение границ. Я застрял в поиске ближайшей линии к краю обнаруженной фигуры. На самом деле я взял пример кода с веб-сайта OpenCV:https://docs.opencv.org/4.1.0/d0/d49/tutorial_moments.html
Хотя я немного понимаю, но не могу реализовать такой код. Я искал такого рода вопросы, но не смог найти ни здесь, ни где-либо еще.
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <iomanip>
using namespace cv;
using namespace std;
Mat src_gray;
int thresh = 100;
RNG rng(12345);
/// Function header
void thresh_callback(int, void*);
int main(int argc, char** argv)
{
/// Load source image
CommandLineParser parser(argc, argv, "{@input | circles_rectangles.jpg | input image}");
Mat src = imread(parser.get<String>("@input"));
if (src.empty())
{
cout << "Could not open or find the image!n" << endl;
cout << "usage: " << argv[0] << " <Input image>" << endl;
return -1;
}
/// Convert image to gray and blur it
cvtColor(src, src_gray, COLOR_BGR2GRAY);
blur(src_gray, src_gray, Size(3, 3));
/// Create Window
const char* source_window = "Source";
namedWindow(source_window);
imshow(source_window, src);
const int max_thresh = 255;
createTrackbar("Canny thresh:", source_window, amp;thresh, max_thresh, thresh_callback);
thresh_callback(0, 0);
waitKey();
return 0;
}
/**
* @function thresh_callback
*/
void thresh_callback(int, void*)
{
/// Detect edges using canny
Mat canny_output;
Canny(src_gray, canny_output, thresh, thresh * 2, 3);
/// Find contours
vector<vector<Point> > contours;
findContours(canny_output, contours, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
/// Get the moments
vector<Moments> mu(contours.size());
for (size_t i = 0; i < contours.size(); i )
{
mu[i] = moments(contours[i]);
}
/// Get the mass centers
vector<Point2f> mc(contours.size());
for (size_t i = 0; i < contours.size(); i )
{
//add 1e-5 to avoid division by zero
mc[i] = Point2f(static_cast<float>(mu[i].m10 / (mu[i].m00 1e-5)),
static_cast<float>(mu[i].m01 / (mu[i].m00 1e-5)));
cout << "mc[" << i << "]=" << mc[i] << endl;
}
/// Draw contours
Mat drawing = Mat::zeros(canny_output.size(), CV_8UC3);
for (size_t i = 0; i < contours.size(); i )
{
Scalar color = Scalar(rng.uniform(0, 256), rng.uniform(0, 256), rng.uniform(0, 256));
drawContours(drawing, contours, (int)i, color, 2);
circle(drawing, mc[i], 4, color, -1);
}
/// Show in a window
imshow("Contours and center", drawing);
/// Calculate the area with the moments 00 and compare with the result of the OpenCV function
cout << "t Info: Area and Contour Length n";
for (size_t i = 0; i < contours.size(); i )
{
cout << " * Contour[" << i << "] - Area (M_00) = " << std::fixed << std::setprecision(2) << mu[i].m00
<< " - Area OpenCV: " << contourArea(contours[i]) << " - Length: " << arcLength(contours[i], true) << endl;
}
}
Вот изображение для отладки:https://imgur.com/Ymbu48a
Вот отлаженная версия:https://imgur.com/AFE9ZB1
И вот что я ожидаю сделать:https://imgur.com/MUfxikI
Есть предложения, как это сделать?
Комментарии:
1. Я не совсем понял ваш вопрос? Вам нужно предложение алгоритма или отладка этого кода?
2. Контур — это список точек. Вы могли бы перебирать их и вычислять расстояние, чтобы найти ближайший.
3. @Meisam Я не могу отладить код. Мой вопрос буквально заключается в нахождении линии от центра фигуры до ближайшего края.
4. @J.D. например, найти минимальное расстояние, проверив все точки от центра до края? есть ли какая-либо функция для этого?
5. Насколько я знаю (хотя я не эксперт), но вы можете найти расстояние для каждой точки, используя теорему Пифагора, где
a = abs(point.x-center.x)
иb = abs(point.y-center.y)
. Проверьте все точки каждой фигуры относительно ее центра, чтобы найти наименьшуюc
.