algoLib/sourceCode/WD_watershed.cpp

366 lines
10 KiB
C++
Raw Normal View History

2025-11-10 22:44:31 +08:00
#if 0
#include <iostream>
#include <vector>
#include <queue>
#include <cmath>
#include <cstring>
#include <fstream>
using namespace std;
// ͼ<><CDBC><EFBFBD>ߴ<EFBFBD>
const int WIDTH = 256;
const int HEIGHT = 256;
// 8<><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dy[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
// <20><><EFBFBD>ؽṹ
struct Pixel {
int x, y; // <20><><EFBFBD><EFBFBD>
int value; // <20><><EFBFBD><EFBFBD>ֵ(<28>Ҷ<EFBFBD>)
Pixel(int x_, int y_, int v_) : x(x_), y(y_), value(v_) {}
// <20><><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ıȽϺ<C8BD><CFBA><EFBFBD>(С<><D0A1><EFBFBD><EFBFBD>)
bool operator<(const Pixel& other) const {
return value > other.value; // ע<><EFBFBD><E2A3BA><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD>Ǵ󶥶ѣ<F3B6A5B6><D1A3><EFBFBD><EFBFBD>ﷴת<EFB7B4>Ƚ<EFBFBD>
}
};
// <20><>ȡPGM<47><4D>ʽͼ<CABD><CDBC>
bool readPGM(const string& filename, int image[HEIGHT][WIDTH]) {
ifstream file(filename, ios::binary);
if (!file) return false;
string magic;
int w, h, max_val;
file >> magic >> w >> h >> max_val;
if (magic != "P5" || w != WIDTH || h != HEIGHT) return false;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>з<EFBFBD>
file.ignore(1);
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ֵ
unsigned char pixel;
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j) {
file.read((char*)&pixel, 1);
image[i][j] = (int)pixel;
}
}
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ΪPGMͼ<4D><CDBC>
void writePGM(const string& filename, int labels[HEIGHT][WIDTH], int num_labels) {
ofstream file(filename, ios::binary);
file << "P5\n" << WIDTH << " " << HEIGHT << "\n255\n";
// <20><><EFBFBD><EFBFBD>ǩӳ<C7A9>䵽0-255<35><35>Χ
int step = 255 / (num_labels + 1);
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j) {
unsigned char val = (labels[i][j] + 1) * step;
if (labels[i][j] == -1) val = 0; // <20><>ˮ<EFBFBD><CBAE><EFBFBD>߽<EFBFBD>
file.write((char*)&val, 1);
}
}
}
// <20><>ˮ<EFBFBD><CBAE><EFBFBD>㷨ʵ<E3B7A8><CAB5>
int watershed(int image[HEIGHT][WIDTH], int labels[HEIGHT][WIDTH]) {
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>ǩ<EFBFBD><C7A9>-1<><31>ʾδ<CABE><CEB4><EFBFBD>ǣ<EFBFBD>0<EFBFBD><30>ʾ<EFBFBD>߽<EFBFBD>
memset(labels, -1, sizeof(int) * HEIGHT * WIDTH);
// <20><><EFBFBD>ȶ<EFBFBD><C8B6><EFBFBD>(<28><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>С<EFBFBD><D0A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>)
priority_queue<Pixel> pq;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>оֲ<D0BE><D6B2><EFBFBD>Сֵ<D0A1><D6B5>Ϊ<EFBFBD><CEAA>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
int current_label = 0;
bool is_min;
// <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD>ҵ<EFBFBD><D2B5><EFBFBD><EFBFBD>оֲ<D0BE><D6B2><EFBFBD>Сֵ<D0A1><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
for (int i = 0; i < HEIGHT; ++i) {
for (int j = 0; j < WIDTH; ++j) {
is_min = true;
for (int d = 0; d < 8; ++d) {
int ni = i + dx[d];
int nj = j + dy[d];
if (ni >= 0 && ni < HEIGHT && nj >= 0 && nj < WIDTH) {
if (image[ni][nj] < image[i][j]) {
is_min = false;
break;
}
}
}
if (is_min) {
labels[i][j] = current_label++;
pq.push(Pixel(i, j, image[i][j]));
}
}
}
// <20>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD><EFBFBD>
while (!pq.empty()) {
Pixel p = pq.top();
pq.pop();
int x = p.x;
int y = p.y;
for (int d = 0; d < 8; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx >= 0 && nx < HEIGHT && ny >= 0 && ny < WIDTH) {
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>δ<EFBFBD><CEB4><EFBFBD><EFBFBD>
if (labels[nx][ny] == -1) {
// <20><><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD>
labels[nx][ny] = labels[x][y];
pq.push(Pixel(nx, ny, image[nx][ny]));
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><D1B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>ͬ<EFBFBD><CDAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>߽<EFBFBD>
else if (labels[nx][ny] != labels[x][y]) {
labels[x][y] = -1; // <20><>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD>߽<EFBFBD>
}
}
}
}
return current_label;
}
#if 0
<EFBFBD>˵<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѭ<EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ļ<EFBFBD><EFBFBD><EFBFBD>ԭ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>α<EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ĻҶ<EFBFBD>ֵ<EFBFBD><EFBFBD>Ϊ<EFBFBD><EFBFBD><EFBFBD>θ߶ȣ<EFBFBD><EFBFBD>Ҷ<EFBFBD>ֵԽ<EFBFBD>ͱ<EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Խ<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʶ<EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>е<EFBFBD><EFBFBD><EFBFBD><EFBFBD>оֲ<EFBFBD><EFBFBD><EFBFBD>Сֵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Щ<EFBFBD>dz<EFBFBD>ʼ<EFBFBD><EFBFBD> "<EFBFBD><EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>"
<EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD>ʹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȶ<EFBFBD><EFBFBD>У<EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ѣ<EFBFBD>ģ<EFBFBD><EFBFBD><EFBFBD>ӵ͵<EFBFBD><EFBFBD>ߵ<EFBFBD><EFBFBD><EFBFBD>û<EFBFBD><EFBFBD><EFBFBD>̣<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><EFBFBD>С<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ÿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ر<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD>߽<EFBFBD>ȷ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD>ص<EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD>γɷ<EFBFBD>ˮ<EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD>
ʹ<EFBFBD>÷<EFBFBD><EFBFBD><EFBFBD>
׼<EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD> 256x256 <EFBFBD><EFBFBD> PGM <EFBFBD><EFBFBD>ʽ<EFBFBD>Ҷ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊinput.pgm
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>g++ watershed.cpp - o watershed
<EFBFBD><EFBFBD><EFBFBD>г<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>. / watershed
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ϊoutput.pgm<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>в<EFBFBD>ͬ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ò<EFBFBD>ͬ<EFBFBD>Ҷȱ<EFBFBD>ʾ<EFBFBD><EFBFBD><EFBFBD>߽<EFBFBD>Ϊ<EFBFBD><EFBFBD>ɫ
ע<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD><EFBFBD><EFBFBD>ǻ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>û<EFBFBD>м<EFBFBD><EFBFBD><EFBFBD>Ԥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȥ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܶԸ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD>Ч<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
ʵ<EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD>ȶ<EFBFBD>ͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ٹ<EFBFBD><EFBFBD>ȷָ<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͨ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʽ<EFBFBD><EFBFBD>4 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 8 <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ı<EFBFBD><EFBFBD>ָ<EFBFBD>Ч<EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>ɫͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD>ת<EFBFBD><EFBFBD>Ϊ<EFBFBD>Ҷ<EFBFBD>ͼ<EFBFBD>ٴ<EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߴ<EFBFBD><EFBFBD><EFBFBD>ͼ<EFBFBD>񣬿<EFBFBD><EFBFBD><EFBFBD><EFBFBD>޸<EFBFBD>WIDTH<EFBFBD><EFBFBD>HEIGHT<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڴ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int main() {
int image[HEIGHT][WIDTH];
int labels[HEIGHT][WIDTH];
// <20><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD>ͼ<EFBFBD><CDBC>
if (!readPGM("input.pgm", image)) {
cerr << "<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><EFBFBD><EFBFBD>" << endl;
return -1;
}
// ִ<>з<EFBFBD>ˮ<EFBFBD><CBAE><EFBFBD>
int num_labels = watershed(image, labels);
cout << "<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>õ<EFBFBD> " << num_labels << " <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << endl;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
writePGM("output.pgm", labels, num_labels);
cout << "<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><EFBFBD><EFBFBD>Ϊ output.pgm" << endl;
return 0;
}
#endif
#else
#include <iostream>
#include <vector>
#include <queue>
#include <algorithm>
#include <fstream>
#include <cmath>
#include "SG_baseDataType.h"
#include "SG_baseAlgo_Export.h"
using namespace std;
#if 0
// <20><>ȡPPM<50><4D>ʽͼ<CABD>񣨼򻯰棩
bool readPPM(const string& filename, Image& img) {
ifstream file(filename, ios::binary);
if (!file) return false;
string magic;
int maxVal;
file >> magic >> img.width >> img.height >> maxVal;
if (magic != "P6") return false; // <20><>֧<EFBFBD>ֶ<EFBFBD><D6B6><EFBFBD><EFBFBD><EFBFBD>PPM
file.ignore(); // <20><><EFBFBD>Ի<EFBFBD><D4BB>з<EFBFBD>
vector<unsigned char> data(img.width * img.height * 3);
file.read((char*)data.data(), data.size());
// תΪ<D7AA>Ҷ<EFBFBD>ͼ<EFBFBD><CDBC>Y = 0.299*R + 0.587*G + 0.114*B<><42>
img.gray.resize(img.height, vector<int>(img.width));
img.markers.resize(img.height, vector<int>(img.width, 0)); // <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͼΪ0
for (int i = 0; i < img.height; ++i) {
for (int j = 0; j < img.width; ++j) {
int idx = (i * img.width + j) * 3;
int r = data[idx];
int g = data[idx + 1];
int b = data[idx + 2];
img.gray[i][j] = (int)(0.299 * r + 0.587 * g + 0.114 * b);
}
}
return true;
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ָ<EFBFBD><D6B8><EFBFBD><EFBFBD><EFBFBD>ΪPPM<50><4D>ʽ
void saveResult(const string& filename, const Image& img) {
ofstream file(filename, ios::binary);
file << "P6\n" << img.width << " " << img.height << "\n255\n";
for (int i = 0; i < img.height; ++i) {
for (int j = 0; j < img.width; ++j) {
if (img.markers[i][j] == -1) { // <20><>ˮ<EFBFBD><CBAE><EFBFBD>߽磨<DFBD><E7A3A8>ɫ<EFBFBD><C9AB>
file.put(255); file.put(0); file.put(0);
}
else { // <20><><EFBFBD>򣨸<EFBFBD><F2A3A8B8>ݱ<EFBFBD><DDB1><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD>ɲ<EFBFBD>ͬ<EFBFBD><CDAC>ɫ<EFBFBD><C9AB>
int color = (img.markers[i][j] * 50) % 256;
file.put(color);
file.put((color + 85) % 256);
file.put((color + 170) % 256);
}
}
}
}
#endif
// 8<><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƫ<EFBFBD><C6AB>
const int dx[] = { -1, -1, -1, 0, 0, 1, 1, 1 };
const int dy[] = { -1, 0, 1, -1, 1, -1, 0, 1 };
// <20><><EFBFBD><EFBFBD><EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD>Сֵ<D0A1><D6B5>Ϊ<EFBFBD><CEAA>ʼ<EFBFBD><CABC><EFBFBD>ӵ<EFBFBD>
void findMinima(SWD_waterShedImage& img, int& markerCount) {
markerCount = 1; //<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ӧ<EFBFBD><D3A6>ID
// <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD><D8A3>ж<EFBFBD><D0B6>Ƿ<EFBFBD>Ϊ<EFBFBD>ֲ<EFBFBD><D6B2><EFBFBD>Сֵ<D0A1><D6B5>8<EFBFBD><38><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1>
for (int i = 1; i < img.height - 1; ++i) {
for (int j = 1; j < img.width - 1; ++j) {
if (1 == img.markers[i][j]) //<2F><><EFBFBD><EFBFBD>
continue;
bool isMin = true;
#if 0
for (int d = 0; d < 8; ++d) {
int y = i + dy[d];
int x = j + dx[d];
if (img.gray[y][x] < img.gray[i][j]) {
isMin = false;
break;
}
}
#else
for (int dy = -7; dy < 7; dy++)
{
for (int dx = -7; dx < 7; dx++)
{
int y = i + dy;
int x = j + dx;
if ((x >= 0) && (x < img.width) && (y >= 0) && (y < img.height))
{
if (img.gray[y][x] < img.gray[i][j]) {
isMin = false;
break;
}
}
}
}
#endif
if (isMin) {
// <20><><EFBFBD><EFBFBD><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD>Сֵ
bool hasMarker = false;
for (int d = 0; d < 8; ++d) {
int y = i + dy[d];
int x = j + dx[d];
if (img.markers[y][x] > 1) {
hasMarker = true;
img.markers[y][x] = img.markers[i][j];
break;
}
}
if (!hasMarker) {
img.markers[i][j] = ++markerCount; // <20><><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>
}
}
}
}
}
// <20><>ˮ<EFBFBD><CBAE><EFBFBD><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
void watershed(SWD_waterShedImage& img)
{
int markerCount;
findMinima(img, markerCount); // <20>Զ<EFBFBD><D4B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӵ<EFBFBD>
// <20><><EFBFBD>Ҷ<EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD>ģ<EFBFBD><C4A3>ˮλ<CBAE><CEBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vector<pair<int, pair<int, int>>> pixels; // (<28>Ҷ<EFBFBD>ֵ, (x,y))
for (int i = 0; i < img.height; ++i) {
for (int j = 0; j < img.width; ++j) {
pixels.emplace_back(img.gray[i][j], make_pair(i, j));
}
}
sort(pixels.begin(), pixels.end());
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>أ<EFBFBD>ִ<EFBFBD><D6B4>עˮ<D7A2><CBAE><EFBFBD><EFBFBD>
for (const auto& p : pixels) {
int x = p.second.first;
int y = p.second.second;
if (img.markers[x][y] > 0) continue; // <20>ѱ<EFBFBD><D1B1>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD>ӵ<EFBFBD>
// <20>ռ<EFBFBD><D5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><D1B1>ǵ<EFBFBD><C7B5><EFBFBD><EFBFBD><EFBFBD>
vector<int> neighborMarkers;
for (int d = 0; d < 8; ++d) {
int nx = x + dx[d];
int ny = y + dy[d];
if (nx >= 0 && nx < img.height && ny >= 0 && ny < img.width) {
int m = img.markers[nx][ny];
if (m > 0) {
neighborMarkers.push_back(m);
}
}
}
if (neighborMarkers.empty()) {
continue; // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ǣ<EFBFBD><C7A3>ݲ<EFBFBD><DDB2><EFBFBD><EFBFBD><EFBFBD>
}
else if (neighborMarkers.size() == 1) {
img.markers[x][y] = neighborMarkers[0]; // <20><><EFBFBD><EFBFBD>ͬһ<CDAC><D2BB><EFBFBD><EFBFBD>
}
else {
// <20><><EFBFBD><EFBFBD><EFBFBD>򽻻㣬<F2BDBBBB><E3A3AC><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>ˮ<EFBFBD><CBAE>
img.markers[x][y] = -1;
}
}
}
#if 0
int main() {
Image img;
if (!readPPM("input.ppm", img)) { // <20><><EFBFBD><EFBFBD>PPMͼ<4D><CDBC>
cerr << "<EFBFBD>޷<EFBFBD><EFBFBD><EFBFBD>ȡͼ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>" << endl;
return -1;
}
watershed(img); // ִ<>з<EFBFBD>ˮ<EFBFBD><CBAE><EFBFBD>ָ<EFBFBD>
saveResult("watershed_result.ppm", img); // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
cout << "<EFBFBD>ָ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ɣ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ѱ<EFBFBD><EFBFBD><EFBFBD>Ϊ watershed_result.ppm" << endl;
return 0;
}
#endif
#endif