/
Gantsou
/
ComputerVision
Обзор
Документация
Войти
/
Gantsou
/
ComputerVision
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
Klette_Computer_Vision_2019/part5/codes/segImgCplus.cpp
141 строка
5 KB
Art_Lun
Клетте глава 5
21 дек 2025, 01:55
21 дек 2025, 01:55
5d76b5d
Код
Авторство
О чём код?
#include <opencv2/opencv.hpp> #include <opencv2/imgproc.hpp> #include <vector> #include <iostream> using namespace cv; using namespace std; // Функция для K-means сегментации Mat kmeansSegmentation(const Mat& src, int k = 3) { Mat samples = src.reshape(1, src.rows * src.cols); Mat samples32f; samples.convertTo(samples32f, CV_32F); Mat labels; Mat centers; // Применение K-means kmeans(samples32f, k, labels, TermCriteria(TermCriteria::EPS + TermCriteria::COUNT, 10, 1.0), 3, KMEANS_PP_CENTERS, centers); // Создание сегментированного изображения Mat segmented(src.size(), src.type()); for (int i = 0; i < src.rows; i++) { for (int j = 0; j < src.cols; j++) { int cluster_idx = labels.at<int>(i * src.cols + j, 0); segmented.at<Vec3b>(i, j) = centers.at<Vec3f>(cluster_idx, 0); } } return segmented; } // Функция для пороговой сегментации Mat thresholdSegmentation(const Mat& src) { Mat gray, binary; // Преобразование в оттенки серого cvtColor(src, gray, COLOR_BGR2GRAY); // Пороговая обработка (метод Оцу) threshold(gray, binary, 0, 255, THRESH_BINARY | THRESH_OTSU); return binary; } // Функция для сегментации методом водораздела Mat watershedSegmentation(const Mat& src) { Mat gray; cvtColor(src, gray, COLOR_BGR2GRAY); // Бинаризация Mat binary; threshold(gray, binary, 0, 255, THRESH_BINARY_INV + THRESH_OTSU); // Удаление шума Mat kernel = getStructuringElement(MORPH_RECT, Size(3, 3)); morphologyEx(binary, binary, MORPH_OPEN, kernel, Point(-1, -1), 2); // Поиск области фона Mat sure_bg; dilate(binary, sure_bg, kernel, Point(-1, -1), 3); // Поиск области переднего плана Mat dist_transform; distanceTransform(binary, dist_transform, DIST_L2, 5); Mat sure_fg; double maxVal; minMaxLoc(dist_transform, 0, &maxVal, 0, 0); threshold(dist_transform, sure_fg, 0.7 * maxVal, 255, THRESH_BINARY); // Нахождение неизвестной области sure_fg.convertTo(sure_fg, CV_8U); Mat unknown; subtract(sure_bg, sure_fg, unknown); // Маркировка компонентов Mat markers; connectedComponents(sure_fg, markers); markers = markers + 1; markers.setTo(0, unknown == 255); // Применение алгоритма водораздела Mat markers32s; markers.convertTo(markers32s, CV_32S); watershed(src, markers32s); // Визуализация результатов Mat result = Mat::zeros(markers32s.size(), CV_8UC3); for (int i = 0; i < markers32s.rows; i++) { for (int j = 0; j < markers32s.cols; j++) { int index = markers32s.at<int>(i, j); if (index == -1) { result.at<Vec3b>(i, j) = Vec3b(255, 0, 0); // Границы - синий } else if (index > 1) { // Разные цвета для разных сегментов result.at<Vec3b>(i, j) = Vec3b( (index * 50) % 256, (index * 100) % 256, (index * 150) % 256 ); } } } return result; } int main() { // Загрузка изображения Mat image = imread("input.jpg"); if (image.empty()) { cerr << "Could not load image!" << endl; return -1; } // 1. K-means сегментация Mat kmeans_result = kmeansSegmentation(image, 4); // 2. Пороговая сегментация Mat threshold_result = thresholdSegmentation(image); // 3. Сегментация методом водораздела Mat watershed_result = watershedSegmentation(image); // Отображение результатов imshow("Original", image); imshow("K-means Segmentation", kmeans_result); imshow("Threshold Segmentation", threshold_result); imshow("Watershed Segmentation", watershed_result); // Сохранение результатов imwrite("kmeans_result.jpg", kmeans_result); imwrite("threshold_result.jpg", threshold_result); imwrite("watershed_result.jpg", watershed_result); waitKey(0); return 0; }