ios - 更改 UIImage 中的白色像素
问题描述
我有一个 UIImage,它是一个轮廓,一个是填充的,两者都是从 OpenCV 创建的,一个来自抓取切割,另一个来自结构化元素。
我的两个图像是这样的:
我正在尝试更改轮廓图像中的所有白色像素,因为我想将两个图像合并在一起,所以我最终得到一个红色轮廓和中间的白色填充区域。我正在使用它来将两者合并在一起,并且我知道它不是红色而是粉红色和灰色而不是白色,因为我只是将它们与 alpha 混合在一起。
// Start an image context
UIGraphicsBeginImageContext(grabcutResult.size)
// Create rect for this draw session
let rect = CGRect(x: 0.0, y: 0.0, width: grabcutResult.size.width, height: grabcutResult.size.height)
grabcutResult.draw(in: rect)
redGrabcutOutline.draw(in: rect, blendMode: .normal, alpha: 0.5)
let finalImage = UIGraphicsGetImageFromCurrentImageContext()
这个想法是它应该看起来像这样。
我希望能够快速完成此操作,但我发现的唯一解决方案是针对 ImageView(它只影响内容的呈现方式而不影响底层 UIImage),或者它们涉及逐个像素地循环整个图像。
我正在尝试找到一种解决方案,它将轮廓中的所有白色像素都掩盖为红色,而不必逐个像素地循环整个图像,因为它太慢了。
理想情况下,如果我能让 openCV 只返回红色轮廓而不是白色轮廓会很好,但我认为不可能改变它(也许我错了)。
顺便说一句,使用 swift ......但任何帮助表示赞赏,在此先感谢。
解决方案
这个想法是bitwise-or
将两个掩码“合并”在一起,这两个掩码。由于这个新的组合灰度图像仍然是单个(1 通道)图像,我们需要将其转换为 3 通道,以便我们可以将颜色应用于图像。最后,我们用红色为轮廓蒙版着色以获得我们的结果
我在 Python OpenCV 中实现了它,但你可以用 Swift 来适应同样的想法
import cv2
# Read in images as grayscale
full = cv2.imread('1.png', 0)
outline = cv2.imread('2.png', 0)
# Bitwise-or masks
combine = cv2.bitwise_or(full, outline)
# Combine to 3 color channel and color outline red
combine = cv2.merge([combine, combine, combine])
combine[outline > 120] = (57,0,204)
cv2.imshow('combine', combine)
cv2.waitKey()
使用 IPython 进行基准测试
In [3]: %timeit combine()
782 µs ± 10.4 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
使用 Numpy 的 Vectorized 功能,它似乎相当快
推荐阅读
- c++ - 如何通过 static_assert 检查函数签名是否正确
- reactjs - 使用 ReactJS 单击按钮时如何定向到新页面?
- javascript - 使用随机答案应用程序创建随机问题
- google-cloud-data-fusion - 使用自定义名称将零件文件缝合到一个
- macos - Perl 模块安装 Mac OSX Gatekeeper
- android - 是否有适用于 Razorpay 的 React Native 自定义 SDK
- python - 通过 Airflow 将文件从 GCS 复制到 Google Drive
- api - Revolut 商家 API,沙盒支付失败
- apache-spark - 错误:连接中缺少已解决的属性
- r - Program to iterate through lists within a list