首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >从具有像素值之和<阈值的图像中删除连接分量

从具有像素值之和<阈值的图像中删除连接分量
EN

Stack Overflow用户
提问于 2018-02-07 16:52:45
回答 2查看 1.2K关注 0票数 3

简单地说,这是一个可用的输入和相应的输出的例子:

代码语言:javascript
运行
复制
In: [ 0 0 0 0 0 0 1 0 1 0
      0 6 6 0 0 0 0 1 1 0
      0 8 9 0 0 0 0 0 1 1
      8 0 0 0 9 9 0 0 0 0
      0 0 0 0 8 8 0 0 0 0
      0 0 0 0 0 0 0 0 0 0
      9 9 7 0 0 0 0 0 1 0
      0 6 8 0 0 0 0 3 2 0
      0 0 0 0 0 0 0 2 1 0
      0 0 0 0 0 0 0 0 0 0 ]

二值化后用cv2.connectedComponents()获取标记图像

代码语言:javascript
运行
复制
labels: [ 0 0 0 0 0 0 1 0 1 0
          0 2 2 0 0 0 0 1 1 0
          0 2 2 0 0 0 0 0 1 1
          2 0 0 0 3 3 0 0 0 0
          0 0 0 0 3 3 0 0 0 0
          0 0 0 0 0 0 0 0 0 0
          4 4 4 0 0 0 0 0 5 0
          0 4 4 0 0 0 0 5 5 0
          0 0 0 0 0 0 0 5 5 0
          0 0 0 0 0 0 0 0 0 0 ]

从这里开始,我希望得到以下输出:

代码语言:javascript
运行
复制
Out: [0 0 0 0 0 0 0 0 0 0
      0 6 6 0 0 0 0 0 0 0
      0 8 9 0 0 0 0 0 0 0
      8 0 0 0 9 9 0 0 0 0
      0 0 0 0 8 8 0 0 0 0
      0 0 0 0 0 0 0 0 0 0
      9 9 7 0 0 0 0 0 0 0
      0 6 8 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0
      0 0 0 0 0 0 0 0 0 0 ]

有许多连接的组件存在(在本例中:5个8-连接组件)。(中的中的)像素之和< 10 (一个阈值)的组件在Out中删除。

如何在C++ (可能使用OpenCV)中实现这一点?

我已经在Python上使用OpenCV完成了它,但是无法在C++上实现。

这是我的Python代码的一部分,如果有用的话( cv2.connectedComponents()的输出是标签 ):

代码语言:javascript
运行
复制
for cnt in range(1, labels.max()+1): 
        idx = np.where(labels.copy() == cnt)
        valMat = In[idx]
        sum_valMat = sum(valMat)
        if sum_valMat > 3000:
            fingerNodes[idx] = 0

输入是一个简单的二维矩阵。这是一个连接组件的示例:

EN

Stack Overflow用户

发布于 2018-02-08 05:12:21

您已经在Python中实现了这一点,所以您知道如何解决这个问题。我想,能够在C++中实现它是一个了解您想要使用的库的问题。

您的Python实现效率很低:遍历标签,对于每个标签访问每个图像像素(idx = np.where(labels.copy() == cnt))。如果你有更多的标签,这会变得非常昂贵。

在下面的代码中,我循环遍历图像一次以累积每个标签的图像强度之和,然后一次用计算的和绘制图像(对于带有标签的每个像素,查找该标签的和),然后再一次对该图像进行阈值处理。然后,我使用这个阈值图像作为掩码,将输入图像中不想保留的像素设置为0。

我这里用DIPlib。不过,如果您真的想使用OpenCV,我相信您可以以某种方式复制它。

代码语言:javascript
运行
复制
#include "diplib.h"
#include "dipviewer.h"
#include "diplib/file_io.h"
#include "diplib/regions.h"
#include "diplib/measurement.h"

int main() {
   // Create a test image with similar properties to your example
   dip::Image input = -dip::ImageReadICS( "/Users/cris/newdip/examples/cermet.ics" );
   input.At( input < 120 ) = 0;
   // Display
   dip::viewer::ShowSimple( input, "input image" );
   // Threshold and label
   dip::Image label = dip::Label( input > 0 );
   // Obtain sum of pixels per label
   dip::MeasurementTool measurementTool;
   auto msr = measurementTool.Measure( label, input, { "Mass" } );
   // Paint each label with the measured value
   dip::Image feature = dip::ObjectToMeasurement( label, msr[ "Mass" ] );
   // Create output as a copy of the input, with low feature values set to 0
   dip::Image output = input.Copy();
   output.At( feature < 100000 ) = 0;
   // Display
   dip::viewer::ShowSimple( output, "output image" );
   dip::viewer::Spin();
}

票数 2
EN
查看全部 2 条回答
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48669181

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档