ios - 来自 Swift 代码的抗锯齿像素被 OpenCV 转换为不需要的黑色像素

标签 ios swift opencv image-processing antialiasing

我正在尝试通过将抗锯齿设置为 true 并将路径像素移除为透明来使用 swift 代码使某些像素透明。对于进一步的处理,我使用将路径边缘转换为黑色像素的 C++ 将 UIimage 发送到 opencv。 我想删除不需要的黑色像素。我如何去除 opencv 生成的那些黑色像素?

在opencv中,只是将image转mat,mat转UIImage,同样的问题。

快速代码:

guard let imageSize=image.size else{
            return
        }
        UIGraphicsBeginImageContextWithOptions(imageSize,false,1.0)
        guard let context = UIGraphicsGetCurrentContext() else{
            return
        }
        context.setShouldAntialias(true)
        context.setAllowsAntialiasing(true)
        context.setShouldSubpixelQuantizeFonts(true)
        context.interpolationQuality = .high
        imgCanvas.image?.draw(in: CGRect(x: 0, y:0, width: (imgCanvas.image?.size.width)!, height: (imgCanvas.image?.size.height)!))
        bezeirPath = UIBezierPath()
        bezeirPath.move(to: fromPoint)
        bezeirPath.addLine(to: toPoint)
        bezeirPath.lineWidth=(CGFloat(widthOfLine) * scaleX )/scrollView.zoomScale
        bezeirPath.lineCapStyle = CGLineCap.round
        bezeirPath.lineJoinStyle=CGLineJoin.round
        bezeirPath.flatness=0.0
        bezeirPath.miterLimit=0.0
        bezeirPath.usesEvenOddFillRule=true
        UIColor.white.setStroke()
        bezeirPath.stroke(with: .clear, alpha:0)
        bezeirPath.close()
        bezeirPath.fill()
        UIColor.clear.set()
        context.addPath(bezeirPath.cgPath)
        let image = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()

opencv代码:

Mat source;
    UIImageToMat(originalImage,source,true);

    return MatToUIImage(source);

我尝试了各种方法来解决这个问题,查看了不同的来源,但都没有奏效。在过去的三天里,我一直在努力解决这个问题。因此,如果有人对这个问题有任何线索,那将很有帮助! [ in picture you can see black pixels near transparent edge that is unwanted pixels that black pixels  is produce by opencv [1]

最佳答案

我会将 RGB 图像和 A 掩码作为单独的图像提供给 OpenCV。将蒙版绘制成单 channel 图像:

guard let imageSize=image.size else{
        return
    }
    UIGraphicsBeginImageContextWithOptions(imageSize,false,1.0)
    guard let context = UIGraphicsGetCurrentContext() else{
        return
    }
    context.setShouldAntialias(true)
    context.setAllowsAntialiasing(true)
    context.setShouldSubpixelQuantizeFonts(true)
    context.interpolationQuality = .high
    context.setFillColor(UIColor.black.cgColor)
    context.addRect(CGRect(x: 0, y: 0, width: imageSize.width, height: imageSize.height))
    context.drawPath(using: .fill)
    bezeirPath = UIBezierPath()
    bezeirPath.move(to: fromPoint)
    bezeirPath.addLine(to: toPoint)
    bezeirPath.lineWidth=(CGFloat(widthOfLine) * scaleX )/scrollView.zoomScale
    bezeirPath.lineCapStyle = CGLineCap.round
    bezeirPath.lineJoinStyle=CGLineJoin.round
    bezeirPath.flatness=0.0
    bezeirPath.miterLimit=0.0
    bezeirPath.usesEvenOddFillRule=true
    UIColor.white.setStroke()
    bezeirPath.stroke()
    bezeirPath.close()
    bezeirPath.fill()
    let maskImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

然后在 OpenCV 中,您可以将 A 图像应用于 RGB 图像。

Mat source, sourceMask
UIImageToMat(image, source, true)
UIImageToMat(maskImage, sourceMask, true)

如果您的图像不是 RGB,您可以转换它:

cvtColor(source, source, CV_RGBA2RGB)

如果你的蒙版不是单 channel 的,你可以转换它:

cvtColor(sourceMask, sourceMask, CV_RGBA2GRAY)

然后将RGB图像分割成 channel :

Mat rgb[3];
split(source, rgb);

然后用 RGB channel 和 alpha channel 创建 RGBA 图像:

Mat imgBGRA;

vector<Mat> channels = {rgb[0], rgb[1], rgb[2], sourceMask};
merge(channels, imgBGRA);

由于您的 mask 是使用抗锯齿创建的,因此上面创建的图像也将具有抗锯齿 alpha。

关于ios - 来自 Swift 代码的抗锯齿像素被 OpenCV 转换为不需要的黑色像素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57140727/

相关文章:

ios - 避免很多 if 条件

swift - 即使设置了合并策略,保存时也会发生 NSConstraintConflicts

swift - layer.border 不起作用?

ios - 如何在苹果 map 上加载JSON数据以放置标记IOS

c# - Xamarin Forms map Pin 标注

c++ - 如何在cv::Mat的一部分中设置零值

c++ - cv::Mat 和深度像素之间的转换*

python - 旋转关键点 numpy 数组

objective-c - 如何将数据从 TextField/TextView 发送到另一个 View ?

ios - 写入 mainBundle plist