【问题标题】:how to add coordinates in the segmentation of the watershed?如何在分水岭的分割中添加坐标?
【发布时间】:2020-08-15 07:45:06
【问题描述】:

我正在开发一个应用程序,它可以根据用户在屏幕上绘制的坐标删除图像的背景。用户在感兴趣的图像周围绘制一个矩形。有了这个,我使用分水岭来分割图像并从图像中删除背景。但是,我无法在算法中插入坐标以便删除整个背景。在下图中,我只选择了 4 个硬币,分割后,我只希望这 4 个硬币留在图像中,其他的消失。然而,这不是正在发生的事情。有人可以根据用户传递的区域帮我做这个删除段吗?

代码:

    typealias Coordinates = Pair<Point, Point>    
    private fun extractForegroundFromBackground(coordinates: Coordinates){
    // TODO: Provide complex object that has both path and extension

    val width: Int
    val height: Int
    val rect = Rect(coordinates.first, coordinates.second)
    width = bitmap.getWidth()
    height = bitmap.getHeight()
    val rgba = Mat()
    val gray_mat = Mat()
    val threeChannel = Mat()

    Utils.bitmapToMat(bitmap, gray_mat)

    Imgproc.cvtColor(gray_mat, rgba, Imgproc.COLOR_RGBA2RGB)

    Imgproc.cvtColor(rgba, threeChannel, Imgproc.COLOR_RGB2GRAY)
    Imgproc.threshold(threeChannel, threeChannel, 100.0, 255.0, Imgproc.THRESH_OTSU)

    Imgproc.GaussianBlur(threeChannel, threeChannel, Size(5.0,5.0), 0.0)
    val edges = Mat()
    Imgproc.Canny(threeChannel, edges, 50.0, 200.0)
    val contours: List<MatOfPoint> = ArrayList()
    val hierarchy = Mat()
    Imgproc.findContours(edges, contours, hierarchy, Imgproc.RETR_EXTERNAL, Imgproc.CHAIN_APPROX_SIMPLE)

    val fg = Mat(rgba.size(), CvType.CV_8U)
    Imgproc.erode(threeChannel, fg, Mat(), Point(-1.0, -1.0), 2)

    val bg = Mat(rgba.size(), CvType.CV_8U)
    Imgproc.dilate(threeChannel, bg, Mat(), Point(-1.0, -1.0), 3)
    Imgproc.threshold(bg, bg, 1.0, 127.0, Imgproc.THRESH_BINARY_INV)
    val markers = Mat(rect.size(), CvType.CV_8U, Scalar(0.0))

    val frame = Mat()
    val rectImage = Mat(rgba.size(), CvType.CV_8U)
    Imgproc.rectangle(rectImage, coordinates.first, coordinates.second, Scalar(255.0, 255.0, 255.0), FILLED)
    Log.i("teste,", coordinates.first.toString() + "\n"+ coordinates.second.toString())
    Core.add(fg, bg, markers, rectImage)

    // Start the WaterShed Segmentation :
    val marker_tempo = Mat()
    markers.convertTo(marker_tempo, CvType.CV_32S)

    Imgproc.watershed(rgba, marker_tempo)
    marker_tempo.convertTo(markers, CvType.CV_8U)

    result_Bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565)

    Imgproc.applyColorMap(markers, markers, COLORMAP_BONE)
    Utils.matToBitmap(markers, result_Bitmap)

    image.setImageBitmap(result_Bitmap)

    return currentPhotoPath
}
}

输出:

【问题讨论】:

  • 能否附上样本输入和预期输出?
  • @ZdaR 我用预期的输出更新了问题。你能帮助我吗?我需要这样做几个星期,但我无法传递坐标,以便分水岭可以从这些坐标中分割并从图像中删除整个背景。

标签: java android opencv kotlin image-processing


【解决方案1】:

最简单的方法是将mask 参数添加到add 方法中。您需要创建 image of rectangle rect 才能使其正常工作。使用厚度 = FILLED 绘制填充矩形。

val rectImage = Mat(rgba.size(), CvType.CV_8U)
Imgproc.rectangle(rectImage, coordinates, Scalar(255, 255, 255), Imgproc.FILLED)

Core.add(fg, bg, markers, rectImage)

其他选项

您可以将markers 图像像素乘以矩形图像。只有矩形内的硬币像素将保留。

但是,在这种情况下,您需要确保要相乘的图像范围为 [0, 1],但您的图像范围为 [0, 255]。因此,为了使其工作,只需将 divide 图像乘以 255,然后 multiply 它们,最后将 multiply 结果乘以 255。还有一种方法 multiply​(Mat src1, Mat src2, Mat dst, double scale) 可以将矩阵相乘,然后将结果乘以一次 255 个。

另一种方法是使用bitwise and 操作。在这种情况下,您无需转换为范围 [0, 1]。

val rectImage = Mat(rgba.size(), CvType.CV_8U)
Imgproc.rectangle(rectImage, coordinates, Scalar(255, 255, 255), Imgproc.FILLED)

val clippedMarkers = Mat(rgba.size(), CvType.CV_8U)
Core.bitwise_and(markers, rectImage, clippedMarkers)

另一种选择是使用copyTo​ 方法。它以掩码为第三个参数。

val rectImage = Mat(rgba.size(), CvType.CV_8U)
Imgproc.rectangle(rectImage, coordinates, Scalar(255, 255, 255), Imgproc.FILLED)

val clippedMarkers = Mat(rgba.size(), CvType.CV_8U)
Core.copyTo(markers, clippedMarkers, rectImage)

【讨论】:

  • 你能帮我在代码中做这个吗,不知道是怎么回事。我按照你的建议做了,结果在我更新的问题中。
  • 看来我把错误的参数放到了Imgproc.rectangle中。它应该是 rectImage 而不是 frame。在我的回答中修复了这个问题
  • 顺便可以输出rectImage来调试你的程序,看看矩形是否渲染正确。
  • 这是正确的......我使用了日志,它给了我划定区域的坐标。
  • 那么,您是否将frame 替换为rectImage 并且结果保持不变,对吧?您是否尝试过其他解决方案(使用bitwise_andcopyTo)?
猜你喜欢
  • 1970-01-01
  • 2012-07-11
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-06-11
  • 2019-08-06
  • 2018-10-26
相关资源
最近更新 更多