Как улучшить сегментацию изображения для алгоритма захвата? - PullRequest
1 голос
/ 21 апреля 2020

Я разрабатываю приложение kotlin для удаления фона с изображений. Для этого я использую захват вместе с координатами области интереса области, которая будет вырезана. Пользователь помечает область прямоугольником, координаты передаются алгоритму, который, в свою очередь, выполняет удаление фона. Однако алгоритм не может работать хорошо на некоторых изображениях и в итоге удаляет области, где его не нужно было удалять, как показано на рисунке ниже. Как улучшить сегментацию изображения для повышения производительности захвата? enter image description here

Выход:

enter image description here

КОД:

typealias Coordinates = Pair<Point, Point>
private fun extractForegroundFromBackground(coordinates: Coordinates, currentPhotoPath: String): String {

    // Matrices that OpenCV will be using internally
    val bgModel = Mat()
    val fgModel = Mat()

    val srcImage = Imgcodecs.imread(currentPhotoPath)
    val iterations = 5

    // Mask image where we specify which areas are background, foreground or probable background/foreground
    val firstMask = Mat()

    val source = Mat(1, 1, CvType.CV_8U, Scalar(Imgproc.GC_PR_FGD.toDouble()))
    val rect = Rect(coordinates.first, coordinates.second)

    // Run the grab cut algorithm with a rectangle (for subsequent iterations with touch-up strokes,
    // flag should be Imgproc.GC_INIT_WITH_MASK)
    Imgproc.grabCut(srcImage, firstMask, rect, bgModel, fgModel, iterations, Imgproc.GC_INIT_WITH_RECT)

    // Create a matrix of 0s and 1s, indicating whether individual pixels are equal
    // or different between "firstMask" and "source" objects
    // Result is stored back to "firstMask"
    Core.compare(firstMask, source, firstMask, Core.CMP_EQ)

    // Create a matrix to represent the foreground, filled with white color
    val foreground = Mat(srcImage.size(), CvType.CV_8UC3, Scalar(255.0, 255.0, 255.0))

    // Copy the foreground matrix to the first mask
    srcImage.copyTo(foreground, firstMask)

    // Create a red color
    val color = Scalar(255.0, 0.0, 0.0, 255.0)
    // Draw a rectangle using the coordinates of the bounding box that surrounds the foreground
    Imgproc.rectangle(srcImage, coordinates.first, coordinates.second, color)

    // Create a new matrix to represent the background, filled with white color
    val background = Mat(srcImage.size(), CvType.CV_8UC3, Scalar(0.0, 0.0, 0.0))

    val mask = Mat(foreground.size(), CvType.CV_8UC1, Scalar(255.0, 255.0, 255.0))
    // Convert the foreground's color space from BGR to gray scale
    Imgproc.cvtColor(foreground, mask, Imgproc.COLOR_BGR2GRAY)

    // Separate out regions of the mask by comparing the pixel intensity with respect to a threshold value
    Imgproc.threshold(mask, mask, 254.0, 255.0, Imgproc.THRESH_BINARY_INV)

    // Create a matrix to hold the final image
    val dst = Mat()
    // copy the background matrix onto the matrix that represents the final result
    background.copyTo(dst)

    val vals = Mat(1, 1, CvType.CV_8UC3, Scalar(0.0))
    // Replace all 0 values in the background matrix given the foreground mask
    background.setTo(vals, mask)

    // Add the sum of the background and foreground matrices by applying the mask
    Core.add(background, foreground, dst, mask)

    // Save the final image to storage
    Imgcodecs.imwrite(currentPhotoPath + "_tmp.png", dst)

    // Clean up used resources
    firstMask.release()
    source.release()
    bgModel.release()
    fgModel.release()
    vals.release()
    dst.release()

    return currentPhotoPath
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...