bra*_*ipt 6 image-comparison image-processing core-image ios swift
我正在使用Swift为iOS构建这个 - 通过CoreImage或GPUImage,但如果我可以用Python或Node/JavaScript构建它,那也是有用的.随意抽象地回答,或者完全用不同的语言回答 - 我会接受任何大致描述我如何实现这个目标的答案.
考虑以下两个"图像"(我制作了两个3x3像素网格来表示两个图像,每个3x3像素,总共9个像素).
假设我使用着色器处理原始图像(左),该着色器改变某些像素但不是所有像素的颜色.右边的结果图像是相同的,但对于3个像素 - #2,#3和#6:
我试图找到一种方法来比较两个图像中的所有像素,并记录在过滤过程中未改变的像素的x,y位置.在这种情况下,当从左到右进行比较时,我需要知道#1,#4,#5,#7,#8和#9保持不变.
假设您之前和之后的图像大小相同,您需要做的就是遍历每个像素并比较它们可以用指针做的事情.我当然不认为这是最快的方法,但它应该工作(注意你可以用UInt32指针同时比较所有32位,但我正在按字节方式做,只是为了说明RGBA值在你需要的地方) .另请注意,由于Quartz是为Mac编写的,而且它使用的是笛卡尔坐标,而iOS和UIKit则没有,因此可能您的数据是颠倒的(镜像在X轴周围).你必须检查; 这取决于内部位图的表示方式.
func difference(leftImage: UIImage, rightImage: UIImage) {
let width = Int(leftImage.size.width)
let height = Int(leftImage.size.height)
guard leftImage.size == rightImage.size else {
return
}
if let cfData1:CFData = leftImage.cgImage?.dataProvider?.data,
let l = CFDataGetBytePtr(cfData1),
let cfData2:CFData = rightImage.cgImage?.dataProvider?.data,
let r = CFDataGetBytePtr(cfData2) {
let bytesPerpixel = 4
let firstPixel = 0
let lastPixel = (width * height - 1) * bytesPerpixel
let range = stride(from: firstPixel, through: lastPixel, by: bytesPerpixel)
for pixelAddress in range {
if l.advanced(by: pixelAddress).pointee != r.advanced(by: pixelAddress).pointee || //Red
l.advanced(by: pixelAddress + 1).pointee != r.advanced(by: pixelAddress + 1).pointee || //Green
l.advanced(by: pixelAddress + 2).pointee != r.advanced(by: pixelAddress + 2).pointee || //Blue
l.advanced(by: pixelAddress + 3).pointee != r.advanced(by: pixelAddress + 3).pointee { //Alpha
print(pixelAddress)
// do stuff here
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
如果您需要更快的方法,请编写一个着色器,该着色器将对每个像素进行增量并将结果写入纹理.输出中任何不清晰黑色(即0,0,0,0)的像素在图像之间是不同的.着色器不是我的专业领域所以我会留给别人写.此外,在一些架构上,读回昂贵的图形内存是昂贵的,所以你必须测试并看看这是否真的比在主内存中做得更好(也可能取决于图像大小,因为你必须分摊纹理的设置成本和着色器).
| 归档时间: |
|
| 查看次数: |
891 次 |
| 最近记录: |