鱼C论坛

 找回密码
 立即注册
查看: 43|回复: 11

C++图形轮廓提取

[复制链接]
发表于 5 小时前 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
在C++怎样提取用TIFF库加载的黑白二值图像上面所有图形的外部轮廓,不要提取内部孔洞轮廓,另外轮廓需要提取2像素厚度,如果需要对轮廓进行膨胀需要向内膨胀,不要向外,就像Opencv库的RETR_EXTERNAL,但这里不要使用Opencv库处理,因为我的TIFF库数据是存放在    std::vector<unsigned char> intermediateBuffer(nPixels);数组内,所以需要直接对数组进行处理,转成其它格式的数据比较费时间
小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 5 小时前 | 显示全部楼层
在C++中提取黑白二值图像的外部轮廓(不包含内部孔洞),可以通过以下步骤实现:

  • 首先定义图像尺寸和数据结构
    [code=cpp]
    int width = ...;  // 图像宽度
    int height = ...; // 图像高度
    std::vector<unsigned char> contourBuffer(nPixels, 0); // 轮廓存储
    [/code]
  • 使用边界跟踪算法提取外部轮廓
    [code=cpp]
    for (int y = 1; y < height-1; y++) {
        for (int x = 1; x < width-1; x++) {
            int idx = y * width + x;
            // 当前像素为前景(255),且四邻域有背景(0)则为边界
            if (intermediateBuffer[idx] == 255) {
                if (intermediateBuffer[idx-1] == 0 ||     // 左
                    intermediateBuffer[idx+1] == 0 ||     // 右
                    intermediateBuffer[idx-width] == 0 || // 上
                    intermediateBuffer[idx+width] == 0)   // 下
                {
                    contourBuffer[idx] = 255; // 标记为轮廓
                }
            }
        }
    }
    [/code]
  • 实现向内膨胀2像素厚度
    [code=cpp]
    // 第一遍膨胀
    std::vector<unsigned char> tempBuffer = contourBuffer;
    for (int y = 1; y < height-1; y++) {
        for (int x = 1; x < width-1; x++) {
            int idx = y * width + x;
            if (contourBuffer[idx] == 255) {
                // 向内膨胀:只对原始图像前景区域扩展
                if (intermediateBuffer[idx-1] == 255) tempBuffer[idx-1] = 255;
                if (intermediateBuffer[idx+1] == 255) tempBuffer[idx+1] = 255;
                if (intermediateBuffer[idx-width] == 255) tempBuffer[idx-width] = 255;
                if (intermediateBuffer[idx+width] == 255) tempBuffer[idx+width] = 255;
            }
        }
    }

    // 第二遍膨胀得到2像素厚度
    contourBuffer = tempBuffer;
    for (int y = 1; y < height-1; y++) {
        for (int x = 1; x < width-1; x++) {
            int idx = y * width + x;
            if (tempBuffer[idx] == 255) {
                // 继续向内膨胀
                if (intermediateBuffer[idx-1] == 255) contourBuffer[idx-1] = 255;
                if (intermediateBuffer[idx+1] == 255) contourBuffer[idx+1] = 255;
                if (intermediateBuffer[idx-width] == 255) contourBuffer[idx-width] = 255;
                if (intermediateBuffer[idx+width] == 255) contourBuffer[idx+width] = 255;
            }
        }
    }
    [/code]
  • 可选:清理孤立点
    [code=cpp]
    for (int y = 1; y < height-1; y++) {
        for (int x = 1; x < width-1; x++) {
            int idx = y * width + x;
            if (contourBuffer[idx] == 255) {
                // 检查是否为孤立点
                int count = 0;
                count += (contourBuffer[idx-1] == 255);
                count += (contourBuffer[idx+1] == 255);
                count += (contourBuffer[idx-width] == 255);
                count += (contourBuffer[idx+width] == 255);
                if (count == 0) contourBuffer[idx] = 0;
            }
        }
    }
    [/code]


关键点说明:
  • 使用四邻域检测确保只提取外部轮廓
  • 通过两次膨胀操作实现2像素厚度
  • 膨胀时检查 intermediateBuffer 确保只向内膨胀
  • 避免处理图像边界防止越界


最终轮廓数据存储在 contourBuffer 中,可以直接用于后续处理或保存。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 小时前 | 显示全部楼层
FishC 发表于 2025-11-12 15:08
在C++中提取黑白二值图像的外部轮廓(不包含内部孔洞),可以通过以下步骤实现:

这些代码把物体内部的内容轮廓也提取出来了,我只需要图像最外层的轮廓,比如一个黑色的圆,里面有白色的各种图案文字,但我只需要提取圆的外轮廓,至于圆内部的任何轮廓都不要提取
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
cxnet 发表于 2025-11-12 15:18
FishC 发表于 2025-11-12 15:08
在C++中提取黑白二值 ...


要实现只提取最外层轮廓(不包含内部孔洞),可以使用连通组件标记算法。以下是完整的解决方案:

方法一:使用边界标记算法


  1. #include <vector>
  2. #include <queue>
  3. using namespace std;

  4. void extractExternalContours(vector<unsigned char>& image, int width, int height) {
  5.     vector<unsigned char> result(width * height, 0);
  6.     vector<bool> visited(width * height, false);
  7.    
  8.     // 从图像边界开始扫描,标记所有与边界相连的背景
  9.     for (int y = 0; y < height; y++) {
  10.         for (int x = 0; x < width; x++) {
  11.             // 只处理边界像素
  12.             if (x == 0 || x == width-1 || y == 0 || y == height-1) {
  13.                 int idx = y * width + x;
  14.                 if (image[idx] == 0 && !visited[idx]) { // 背景像素
  15.                     // BFS标记所有相连的背景
  16.                     queue<pair<int, int>> q;
  17.                     q.push({x, y});
  18.                     visited[idx] = true;
  19.                     
  20.                     while (!q.empty()) {
  21.                         auto [cx, cy] = q.front();
  22.                         q.pop();
  23.                         
  24.                         int directions[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
  25.                         for (auto [dx, dy] : directions) {
  26.                             int nx = cx + dx, ny = cy + dy;
  27.                             if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
  28.                                 int nidx = ny * width + nx;
  29.                                 if (!visited[nidx] && image[nidx] == 0) {
  30.                                     visited[nidx] = true;
  31.                                     q.push({nx, ny});
  32.                                 }
  33.                             }
  34.                         }
  35.                     }
  36.                 }
  37.             }
  38.         }
  39.     }
  40.    
  41.     // 提取外部轮廓:前景像素且至少有一个邻居是外部背景
  42.     for (int y = 1; y < height-1; y++) {
  43.         for (int x = 1; x < width-1; x++) {
  44.             int idx = y * width + x;
  45.             if (image[idx] == 255) { // 前景像素
  46.                 // 检查4邻域是否有外部背景
  47.                 bool isContour = false;
  48.                 int neighbors[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
  49.                 for (auto [dx, dy] : neighbors) {
  50.                     int nx = x + dx, ny = y + dy;
  51.                     int nidx = ny * width + nx;
  52.                     if (visited[nidx] && image[nidx] == 0) {
  53.                         isContour = true;
  54.                         break;
  55.                     }
  56.                 }
  57.                
  58.                 if (isContour) {
  59.                     result[idx] = 255;
  60.                 }
  61.             }
  62.         }
  63.     }
  64.    
  65.     // 将结果复制回原数组
  66.     image = result;
  67. }
复制代码


方法二:简化版本(适合大多数情况)


  1. void extractOuterContourSimple(vector<unsigned char>& img, int w, int h) {
  2.     vector<unsigned char> contour(w * h, 0);
  3.    
  4.     for (int y = 1; y < h-1; y++) {
  5.         for (int x = 1; x < w-1; x++) {
  6.             int idx = y * w + x;
  7.             if (img[idx] == 255) { // 前景
  8.                 // 检查是否与图像边界背景相连
  9.                 bool touchesBorderBg = false;
  10.                
  11.                 // 检查4方向连接性
  12.                 if (x == 1 && img[idx-1] == 0) touchesBorderBg = true;
  13.                 if (x == w-2 && img[idx+1] == 0) touchesBorderBg = true;
  14.                 if (y == 1 && img[idx-w] == 0) touchesBorderBg = true;
  15.                 if (y == h-2 && img[idx+w] == 0) touchesBorderBg = true;
  16.                
  17.                 // 检查4邻域背景连通性
  18.                 if (!touchesBorderBg) {
  19.                     int dirs[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
  20.                     for (auto [dx, dy] : dirs) {
  21.                         int nx = x + dx, ny = y + dy;
  22.                         int nidx = ny * w + nx;
  23.                         if (img[nidx] == 0) {
  24.                             // 检查这个背景是否能连接到边界
  25.                             vector<bool> checked(w * h, false);
  26.                             queue<pair<int, int>> q;
  27.                             q.push({nx, ny});
  28.                             checked[nidx] = true;
  29.                            
  30.                             while (!q.empty()) {
  31.                                 auto [cx, cy] = q.front();
  32.                                 q.pop();
  33.                                 
  34.                                 // 如果到达边界,则说明是外部轮廓
  35.                                 if (cx == 0 || cx == w-1 || cy == 0 || cy == h-1) {
  36.                                     touchesBorderBg = true;
  37.                                     break;
  38.                                 }
  39.                                 
  40.                                 int ndirs[4][2] = {{1,0},{-1,0},{0,1},{0,-1}};
  41.                                 for (auto [ddx, ddy] : ndirs) {
  42.                                     int nnx = cx + ddx, nny = cy + ddy;
  43.                                     int nnidx = nny * w + nnx;
  44.                                     if (nnx >= 0 && nnx < w && nny >= 0 && nny < h &&
  45.                                         !checked[nnidx] && img[nnidx] == 0) {
  46.                                         checked[nnidx] = true;
  47.                                         q.push({nnx, nny});
  48.                                     }
  49.                                 }
  50.                             }
  51.                             if (touchesBorderBg) break;
  52.                         }
  53.                     }
  54.                 }
  55.                
  56.                 if (touchesBorderBg) {
  57.                     contour[idx] = 255;
  58.                 }
  59.             }
  60.         }
  61.     }
  62.    
  63.     img = contour;
  64. }
复制代码


使用方法:


  1. int main() {
  2.     int width = 800;  // 你的图像宽度
  3.     int height = 600; // 你的图像高度
  4.     int nPixels = width * height;
  5.    
  6.     std::vector<unsigned char> intermediateBuffer(nPixels);
  7.     // ... 从TIFF加载数据到intermediateBuffer ...
  8.    
  9.     // 提取外部轮廓
  10.     extractExternalContours(intermediateBuffer, width, height);
  11.    
  12.     // 现在intermediateBuffer中只包含最外层轮廓
  13.     return 0;
  14. }
复制代码


这两个算法都能确保只提取最外层轮廓:
- 方法一通过标记所有与图像边界相连的背景区域
- 方法二通过检查每个前景像素的背景邻居是否能连接到图像边界

这样就能完美实现类似OpenCV的RETR_EXTERNAL功能,且不包含任何内部孔洞轮廓。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 小时前 | 显示全部楼层
FishC 发表于 2025-11-12 15:20
要实现只提取最外层轮廓(不包含内部孔洞),可以使用连通组件标记算法。以下是完整的解决方案:

方 ...

几种方法函数里面所有的的auto [cx, cy]出错,提示未定义标识符,这应该是什么类型
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
cxnet 发表于 2025-11-12 15:26
FishC 发表于 2025-11-12 15:20
要实现只提取最外层 ...


在C++中,auto 是C++11引入的类型推断关键字。如果编译器报错,可能是由于以下原因:

1. 编译器不支持C++11或更高版本
2. 需要包含必要的头文件

请将代码中的 auto 替换为具体类型:

方法一中的替换:

将:
  1. for (auto neighbor : neighbors)
复制代码

替换为:
  1. for (int i = 0; i < 4; i++) {
  2.     int dx = neighbors[i][0];
  3.     int dy = neighbors[i][1];
  4. }
复制代码


将:
  1. queue<pair<int, int>> q;
复制代码

确保包含头文件:
  1. #include <utility>
复制代码


将:
  1. auto [cx, cy] = q.front();
复制代码

替换为:
  1. int cx = q.front().first;
  2. int cy = q.front().second;
复制代码


完整修改后的代码:

  1. #include <vector>
  2. #include <queue>
  3. #include <utility>
  4. using namespace std;

  5. void extractExternalContours(vector<unsigned char>& image, int width, int height) {
  6.     vector<unsigned char> result(width * height, 0);
  7.     vector<bool> visited(width * height, false);
  8.    
  9.     // 从图像边界开始扫描,标记所有与边界相连的背景
  10.     for (int y = 0; y < height; y++) {
  11.         for (int x = 0; x < width; x++) {
  12.             // 只处理边界像素
  13.             if (x == 0 || x == width-1 || y == 0 || y == height-1) {
  14.                 int idx = y * width + x;
  15.                 if (image[idx] == 0 && !visited[idx]) {
  16.                     // BFS标记所有相连的背景
  17.                     queue<pair<int, int>> q;
  18.                     q.push(make_pair(x, y));
  19.                     visited[idx] = true;
  20.                     
  21.                     while (!q.empty()) {
  22.                         int cx = q.front().first;
  23.                         int cy = q.front().second;
  24.                         q.pop();
  25.                         
  26.                         // 检查4邻域
  27.                         int directions[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
  28.                         for (int i = 0; i < 4; i++) {
  29.                             int nx = cx + directions[i][0];
  30.                             int ny = cy + directions[i][1];
  31.                             if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
  32.                                 int nidx = ny * width + nx;
  33.                                 if (!visited[nidx] && image[nidx] == 0) {
  34.                                     visited[nidx] = true;
  35.                                     q.push(make_pair(nx, ny));
  36.                                 }
  37.                             }
  38.                         }
  39.                     }
  40.                 }
  41.             }
  42.         }
  43.     }
  44.    
  45.     // 提取外部轮廓
  46.     int neighbors[4][2] = {{1,0}, {-1,0}, {0,1}, {0,-1}};
  47.     for (int y = 1; y < height-1; y++) {
  48.         for (int x = 1; x < width-1; x++) {
  49.             int idx = y * width + x;
  50.             if (image[idx] == 255) {
  51.                 bool isContour = false;
  52.                 for (int i = 0; i < 4; i++) {
  53.                     int nx = x + neighbors[i][0];
  54.                     int ny = y + neighbors[i][1];
  55.                     int nidx = ny * width + nx;
  56.                     if (visited[nidx] && image[nidx] == 0) {
  57.                         isContour = true;
  58.                         break;
  59.                     }
  60.                 }
  61.                
  62.                 if (isContour) {
  63.                     result[idx] = 255;
  64.                 }
  65.             }
  66.         }
  67.     }
  68.    
  69.     image = result;
  70. }
复制代码


如果仍有编译问题,请检查编译器是否支持C++11标准,可以在编译时添加 -std=c++11 标志。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 5 小时前 | 显示全部楼层
FishC 发表于 2025-11-12 15:26
在C++中,auto 是C++11引入的类型推断关键字。如果编译器报错,可能是由于以下原因:

1. 编译器不支 ...

为何这次保存出来的图片是全黑底,没有轮廓了
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 5 小时前 | 显示全部楼层
cxnet 发表于 2025-11-12 15:42
FishC 发表于 2025-11-12 15:26
在C++中,auto 是C++ ...


出现全黑图片的问题通常是因为轮廓提取逻辑有误。以下是修正后的代码:


void extractExternalContours(std::vector<unsigned char>& image, int width, int height) {
    std::vector<unsigned char> result(width * height, 0);
    std::vector<bool> externalBackground(width * height, false);
   
    // 标记外部背景(与图像边界相连的背景区域)
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            if (x == 0 || x == width-1 || y == 0 || y == height-1) {
                int idx = y * width + x;
                if (image[idx] == 0 && !externalBackground[idx]) {
                    std::queue<std::pair<int, int>> q;
                    q.push(std::make_pair(x, y));
                    externalBackground[idx] = true;
                    
                    while (!q.empty()) {
                        auto current = q.front();
                        q.pop();
                        int cx = current.first;
                        int cy = current.second;
                        
                        // 检查4邻域
                        int dx[] = {1, -1, 0, 0};
                        int dy[] = {0, 0, 1, -1};
                        
                        for (int i = 0; i < 4; i++) {
                            int nx = cx + dx[i];
                            int ny = cy + dy[i];
                            if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                                int nidx = ny * width + nx;
                                if (!externalBackground[nidx] && image[nidx] == 0) {
                                    externalBackground[nidx] = true;
                                    q.push(std::make_pair(nx, ny));
                                }
                            }
                        }
                    }
                }
            }
        }
    }
   
    // 提取外部轮廓:前景像素且至少有一个邻居是外部背景
    for (int y = 0; y < height; y++) {
        for (int x = 0; x < width; x++) {
            int idx = y * width + x;
            if (image[idx] == 255) { // 前景像素
                bool isContour = false;
               
                // 检查8邻域是否有外部背景
                for (int dy = -1; dy <= 1; dy++) {
                    for (int dx = -1; dx <= 1; dx++) {
                        if (dx == 0 && dy == 0) continue;
                        
                        int nx = x + dx;
                        int ny = y + dy;
                        if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                            int nidx = ny * width + nx;
                            if (externalBackground[nidx]) {
                                isContour = true;
                                break;
                            }
                        }
                    }
                    if (isContour) break;
                }
               
                if (isContour) {
                    result[idx] = 255;
                }
            }
        }
    }
   
    // 将结果复制回原数组
    image = result;
}


主要修正点:
1. 确保包含了必要的头文件:

  1. #include <queue>
  2. #include <utility>  // for std::pair
复制代码


2. 使用8邻域检测而不是4邻域,这样能更好地检测轮廓

3. 确保BFS算法正确标记了所有外部背景像素

4. 确保轮廓检测逻辑正确

如果仍然有问题,请检查:
- 图像数据是否正确加载(确认 intermediateBuffer 中的数据是有效的二值图像)
- 宽度和高度参数是否正确
- 图像数据是否按预期存储(行优先还是列优先)

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
FishC 发表于 2025-11-12 15:08
在C++中提取黑白二值图像的外部轮廓(不包含内部孔洞),可以通过以下步骤实现:

如果我已经将轮廓提取出来了并存入vector<unsigned char> externalContours数组里,我怎样直接用这个轮廓数组将它向内膨胀1像素或者2像素,轮廓需要填充为黑色
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
cxnet 发表于 2025-11-12 17:44
FishC 发表于 2025-11-12 15:08
在C++中提取黑白二值 ...


出现全黑图片的问题可能是由于轮廓提取逻辑有误。以下是修正后的向内膨胀轮廓的代码:


void dilateContourInward(std::vector<unsigned char>& externalContours,
                         const std::vector<unsigned char>& originalImage,
                         int width, int height, int thickness) {
    std::vector<unsigned char> result = externalContours;
   
    for (int t = 0; t < thickness; t++) {
        std::vector<unsigned char> temp = result;
        
        for (int y = 1; y < height-1; y++) {
            for (int x = 1; x < width-1; x++) {
                int idx = y * width + x;
               
                // 如果当前点是轮廓点
                if (result == 255) {
                    // 检查8邻域中的内部点
                    for (int dy = -1; dy <= 1; dy++) {
                        for (int dx = -1; dx <= 1; dx++) {
                            if (dx == 0 && dy == 0) continue;
                           
                            int nx = x + dx;
                            int ny = y + dy;
                            int nidx = ny * width + nx;
                           
                            // 确保在图像范围内
                            if (nx >= 0 && nx < width && ny >= 0 && ny < height) {
                                // 如果邻域点在原始图像中是前景(物体内部)
                                // 并且在当前轮廓中不是轮廓点
                                if (originalImage == 255 && result == 0) {
                                    temp = 255; // 向内膨胀轮廓
                                }
                            }
                        }
                    }
                }
            }
        }
        result = temp;
    }
   
    externalContours = result;
}

使用方法:


// 假设你已经有了:
// std::vector<unsigned char> externalContours - 提取的轮廓
// std::vector<unsigned char> intermediateBuffer - 原始图像
// int width, height - 图像尺寸

// 向内膨胀1像素
dilateContourInward(externalContours, intermediateBuffer, width, height, 1);

// 或者向内膨胀2像素
dilateContourInward(externalContours, intermediateBuffer, width, height, 2);

关键点说明:
1. 使用原始图像 intermediateBuffer 来区分物体内部和外部
2. 只向物体内部方向膨胀(originalImage == 255 的区域)
3. 膨胀厚度由 thickness 参数控制
4. 轮廓点保持为255(白色),背景为0(黑色)

如果仍然有问题,请检查:
1. 确保原始图像 intermediateBuffer 是有效的二值图像
2. 确保轮廓提取函数正确工作
3. 验证图像尺寸参数是否正确

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 3 小时前 | 显示全部楼层
FishC 发表于 2025-11-12 17:46
出现全黑图片的问题可能是由于轮廓提取逻辑有误。以下是修正后的向内膨胀轮廓的代码:

                if (result == 255) {
二进制“==”: 没有找到接受“std::vector<uchar,std::allocator<uchar>>”类型的左操作数的运算符(或没有可接受的转换)
                                if (originalImage == 255 && result == 0) {

二进制“==”: 没有找到接受“const std::vector<uchar,std::allocator<uchar>>”类型的左操作数的运算符(或没有可接受的转换)
                                    temp = 255; // 向内膨胀轮廓
二元“=”: 没有找到接受“int”类型的右操作数的运算符(或没有可接受的转换)
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 3 小时前 | 显示全部楼层
cxnet 发表于 2025-11-12 17:54
FishC 发表于 2025-11-12 17:46
出现全黑图片的问题 ...


抱歉出现了编译错误。以下是修正后的向内膨胀轮廓代码:


void dilateContourInward(std::vector<unsigned char>& externalContours,
                         const std::vector<unsigned char>& originalImage,
                         int width, int height, int thickness) {
    std::vector<unsigned char> result = externalContours;
   
    for (int t = 0; t < thickness; t++) {
        std::vector<unsigned char> temp = result;
        
        for (int y = 1; y < height-1; y++) {
            for (int x = 1; x < width-1; x++) {
                int idx = y * width + x;
               
                // 如果当前点是轮廓点
                if (result[idx] == 255) {
                    // 检查4邻域中属于物体内部但不是轮廓的点
                    int dx[] = {1, -1, 0, 0};
                    int dy[] = {0, 0, 1, -1};
                    
                    for (int i = 0; i < 4; i++) {
                        int nx = x + dx[i];
                        int ny = y + dy[i];
                        int nidx = ny * width + nx;
                        
                        // 如果邻域点属于物体内部但不是轮廓,则将其设为轮廓
                        if (originalImage[nidx] == 255 && result[nidx] == 0) {
                            temp[nidx] = 255; // 向内膨胀轮廓
                        }
                    }
                }
            }
        }
        
        result = temp;
    }
   
    // 将结果复制回原数组
    externalContours = result;
}


这个修正版本:
1. 使用数组索引 result[idx] 而不是直接比较整个vector
2. 使用明确的循环代替auto
3. 确保语法正确

使用方法:

  1. // 假设你已经有了轮廓数组和原图数组
  2. dilateContourInward(externalContours, intermediateBuffer, width, height, 2);
复制代码


这样就会将轮廓向内膨胀2像素厚度。

以上回复来自 FishC AI 小助理,如未能正确解答您的问题,请继续追问。
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-11-12 20:57

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表