# 区域生长算法的一种实现

## 算法流程

1. 选取种子点 QPoint seed(x, y)，用栈来保存种子点区域，将种子点 push 到栈中．
2. 将栈中的种子点 pop 出来，以该点为中心，遍历其八邻域．
3. 判断邻域像素是否已经在种子区域中，若否则判断该像素是否满足生长条件，满足则将其作为新的种子点 push 到栈中．
4. 重复步骤 2-3，直到栈为空．

## 代码实现

// seed 为种子点坐标
// threshold 为一个阈值，若邻域像素与种子点的灰度值之差小于这个阈值
// 则判定其满足生长条件
//
// 这里默认使用了 Qt 的栈 QStack，图像的读写使用 CImg.h 库
void regionGrowth(const QPoint &seed, const int &threshold)
{
// 输入图像
CImg<int> img("test.png");
// 输出结果图像
// 这是一个全白的图片
CImg<int> result(img.width(), img.height(), img.depth(), img.spectrum(), 255);
int T = threshold;
// 用于存储坐标值的临时变量
int x, y;
// 种子栈
QStack<QPoint> seeds;
// 用于存储 pop 出来的种子的临时变量
QPoint currentSeed;
// 将原始的种子压栈
seeds.push(seed);
// 将输出结果图像中对应种子点坐标的灰度值设为0，即黑色
result(seed.x(), seed.y()) = 0;

while(!seeds.isEmpty()) {
// 出栈
currentSeed = seeds.pop();
// 当前种子点的坐标
x = currentSeed.x();
y = currentSeed.y();
// 遍历八邻域
for (int i = -1; i < 2; ++i) {
for (int j = -1; j < 2; ++j) {
// 判断该邻域像素是否在图像内部，避免地址越界的错误
// isInsideImage 函数需要自己实现，比较简单，留给读者自己完成
if (isInsideImage(QPoint(x + i, y + j), img)) {
// 判断是否已经生长过，即结果图像中对应点的灰度值是否为 0
if (result(x + i, y + j) != 0) {
// 生长条件的判断
if (abs(img(x + i, y + j) - img(x, y)) < T) {
// 新种子点压栈
seeds.push(QPoint(x + i, y + j));
// 将结果图像中对应坐标的灰度值设置为 0
result(x + i, y + j) = 0;
}
}
}
}
}
}
// 保存输出结果图像
result.save("result.png");
}
{"ft_lang_label":"__label__zh","ft_lang_prob":0.7096722,"math_prob":0.9966717,"size":1400,"snap":"2019-43-2019-47","text_gpt3_token_len":898,"char_repetition_ratio":0.116762176,"word_repetition_ratio":0.025641026,"special_character_ratio":0.33357143,"punctuation_ratio":0.20987654,"nsfw_num_words":0,"has_unicode_error":false,"math_prob_llama3":0.96099114,"pos_list":[0,1,2],"im_url_duplicate_count":[null,3,null],"WARC_HEADER":"{\"WARC-Type\":\"response\",\"WARC-Date\":\"2019-11-21T01:16:46Z\",\"WARC-Record-ID\":\"<urn:uuid:a88e6f38-9091-496e-95aa-fbd9798d0aca>\",\"Content-Length\":\"17246\",\"Content-Type\":\"application/http; msgtype=response\",\"WARC-Warcinfo-ID\":\"<urn:uuid:3592a4b5-5471-45a1-a23c-e652513cdbdf>\",\"WARC-Concurrent-To\":\"<urn:uuid:026bd809-ccaf-4737-803e-c76c45751d29>\",\"WARC-IP-Address\":\"104.27.169.249\",\"WARC-Target-URI\":\"https://butui.me/post/region-growth-implement-using-c++/\",\"WARC-Payload-Digest\":\"sha1:JO2AKC6UVFM63U4XOM6CBJB3BGNTOQLZ\",\"WARC-Block-Digest\":\"sha1:FOKL37WJV44HSB5B4TC3SZK5KC7OWBX6\",\"WARC-Identified-Payload-Type\":\"text/html\",\"warc_filename\":\"/cc_download/warc_2019/CC-MAIN-2019-47/CC-MAIN-2019-47_segments_1573496670643.58_warc_CC-MAIN-20191121000300-20191121024300-00557.warc.gz\"}"}