/
RDA
/
STZ
Обзор
Документация
Войти
/
RDA
/
STZ
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
lab6/skelet.cpp
120 строк
4 KB
daniil rybyakov
1
11 мар 2025, 00:04
11 мар 2025, 00:04
956e236
Код
Авторство
О чём код?
#include "skelet.hpp" void test_img(cv::Mat img, int x, int y) { if (x == 0 && y == 0) { cv::resize(img, img, cv::Size(3*100, 3*100)); cv::imshow("3*3 img", img); cv::waitKey(2); } if (x != 0 && y != 0) { img.at<uchar>(cv::Point(x,y)) = 255; cv::imshow("test_img", img); cv::waitKey(2); } } int step_A(const cv::Mat rect_3x3) { if (rect_3x3.rows != 3 || rect_3x3.cols != 3) { throw std::invalid_argument("Matrix must be 3x3"); } std::vector<uchar> perimeter; // Координаты по порядку std::vector<cv::Point> points = { {0, 0}, {1, 0}, {2, 0},{2, 1}, {2, 2}, {1, 2}, {0, 2}, {0, 1}}; for (const auto& p : points) perimeter.push_back(rect_3x3.at<uchar>(p)); int A_sum = 0; uchar prev_val = rect_3x3.at<uchar>(cv::Point(0, 1)); for (uchar val : perimeter) { if (val - prev_val > 0) A_sum++; prev_val = val; } return A_sum; } int step_B(const cv::Mat rect_3x3) { if (rect_3x3.rows != 3 || rect_3x3.cols != 3) throw std::invalid_argument("Matrix must be 3x3"); int B_sum = 0; for (int y = 0; y < 3; ++y) for (int x = 0; x < 3; ++x) if (x * y != 1 && rect_3x3.at<uchar>(y, x) > 0) B_sum++; return B_sum; } cv::Mat step_1 (const cv::Mat& input_img) { cv::Mat output_img = input_img.clone(); for (int y = 1; y < input_img.rows - 1; ++y) for (int x = 1; x < input_img.cols - 1; ++x) { cv::Mat rect_3x3 = input_img(cv::Rect(x - 1, y - 1, 3, 3)); //std::cout << y << ", " << x << std::endl; //test_img(input_img.clone(), x, y); //test_img(rect_3x3.clone(), 0, 0); if (input_img.at<uchar>(cv::Point(x, y)) == 0) continue; if (step_B(rect_3x3) < 2 || step_B(rect_3x3) > 6) continue; if (step_A(rect_3x3) != 1) continue; if (rect_3x3.at<uchar>(cv::Point(1, 0)) > 0 && rect_3x3.at<uchar>(cv::Point(2, 1)) > 0 && rect_3x3.at<uchar>(cv::Point(1, 2)) > 0) continue; if (rect_3x3.at<uchar>(cv::Point(2, 1)) > 0 && rect_3x3.at<uchar>(cv::Point(1, 2)) > 0 && rect_3x3.at<uchar>(cv::Point(0, 1)) > 0) continue; output_img.at<uchar>(cv::Point(x, y)) = 0; //cv::imshow("image step_1", output_img); } return output_img; } cv::Mat step_2 (const cv::Mat& input_img) { cv::Mat output_img = input_img.clone(); for (int y = 1; y < input_img.rows - 1; ++y) for (int x = 1; x < input_img.cols - 1; ++x) { cv::Mat rect_3x3 = input_img(cv::Rect(x - 1, y - 1, 3, 3)); if (input_img.at<uchar>(cv::Point(x, y)) == 0) continue; if (step_B(rect_3x3) < 2 || step_B(rect_3x3) > 6) continue; if (step_A(rect_3x3) != 1) continue; if (rect_3x3.at<uchar>(cv::Point(1, 0)) > 0 && rect_3x3.at<uchar>(cv::Point(2, 1)) > 0 && rect_3x3.at<uchar>(cv::Point(0, 1)) > 0) continue; if (rect_3x3.at<uchar>(cv::Point(1, 0)) > 0 && rect_3x3.at<uchar>(cv::Point(1, 2)) > 0 && rect_3x3.at<uchar>(cv::Point(0, 1)) > 0) continue; output_img.at<uchar>(cv::Point(x, y)) = 0; } return output_img; } cv::Mat skelet(cv::Mat img_src) { cv::threshold(img_src, img_src, 127, 255, cv::THRESH_BINARY); cv::Mat img_1, img_2, img_dif; int dif = 1; while (dif != 0) { img_1 = step_1(img_src); img_2 = step_2(img_1); cv::absdiff(img_src, img_2, img_dif); dif = cv::countNonZero(img_dif); img_src = img_2.clone(); } return img_src; }