/
RDA
/
STZ
Обзор
Документация
Войти
/
RDA
/
STZ
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
master
lab7/skelet.cpp
111 строк
3 KB
daniil rybyakov
code visual change 7
11 мар 2025, 10:59
11 мар 2025, 10:59
4db6b32
Код
Авторство
О чём код?
#include "skelet.hpp" int step_A(const cv::Mat rect_3x3) // кол-во переходов от 0 к 1 { 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)); 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; } 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; cv::Mat img_2; cv::Mat 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; }