我的目的是比较两个图像之间的像素,并找出最小(优化的)包含图像之间所有不同像素的矩形区域。 简单地说,我比较了两幅图像的所有像素(例如1024 * 768像素),发现了不同的部分,但由于速度而不是好主意。 我需要做这个比较每秒至少十五次。 你知道更有效的算法吗?查找两个图像之间的不同区域
回答
如果你的像素值存储在二维数组中(比如灰度值为0-255),你可以做的就是像矩阵一样处理数组,然后减去两个数组。结果中的条目是零是相同的像素,非零表示它们是不同的。然后,您会发现包含非零条目的顶部行作为您的y-MAX,您的y-MIN包含非零的最低行,x-MIN包含非零的第一列和非零的最后一列为x-MAX。然后该矩形具有4个坐标:
- (X-MIN,Y-MIN)--lower左角
- (X-MAX,Y-MIN)--lower右上角
- (X- MAX,Y-MAX)--top右上角
- (X-MIN,Y-MAX)--top左侧开出角球
如果你碰巧知道所有的条目都至少为零(可能是通过获取绝对值来完成,但这会增加成本),那么你可以通过右边所有1的列向量乘以矩阵。这会给你一个行数。然后,您会找到第一个和最后一个非零的行数(自上而下搜索,自下而上)。如果你在左边乘以全1的行向量,你会得到相同的结果,但是列总和。再次寻找那些非零的。
矩阵运算很好,因为有优化的库可以帮助加速计算(并且矩阵并不那么大)......特别是如果您有可用于执行计算的GPU。但即使在串行中,小矩阵向量计算也不是那么耗时。
从另一个图像中减去一个图像。相同的像素将变为零,即黑色。
找到一个黑色的角落,并使用trim
(修剪边框/边缘)类型的命令来修剪黑色边框,这将告诉您区别的区域。
这是很简单的ImageMagick的两行做,如果你可以使用 - 它可对C/C多的平台++,Python和Perl中......
让我们两个图像,a.jpg
和b.jpg
:
你看到我做了什么呢? :-)
现在我们可以使用ImageMagick来查找差异和不同的区域。我正在使用命令行,但正如我所说的,您可以使用C/C++,Perl,Python,.NET或其他任何可以漂浮您的船的设备。
要么用它来寻找差异:
convert a.jpg b.jpg \
-compose difference \
-composite \
-threshold 0 \
-separate \
-evaluate-sequence Add \
diff.jpg
其中给出了这样的:
或者使用:
composite a.jpg b.jpg -compose difference diff.jpg
其中给出了这样的:
或者用这个简单的减法:
convert a.jpg b.jpg -compose minus -composite diff.jpg
现在你可以使用ImageMagick的边框装饰功能来评价,如果你修剪所有的黑色边框过什么会留下,像这样:
convert a.jpg b.jpg \
-compose difference \
-composite \
-threshold 0 \
-separate \
-evaluate-sequence Add \
-format "%w %h %@" \
info:
它输出这个:
400 463 264x240+80+176
告诉你图像是400x463,如果你裁剪了边框,你将剩下一个矩形264x240,其左上像素偏移80,176从图像的左上角。
只是为了好玩,我会绘制矩形到图像中的红色,用这个命令:
convert diff.jpg \
-stroke red \
-fill transparent \
-draw "rectangle 80,176 344,416" \
rect.jpg
其中给出了这样的:
从本质上讲,你可以做我的全部在这里用一行或两行shell解释,或者8-10行C/C++。请注意,边界框稍大,因为我叠加的漫画具有透明的矩形背景。如果您需要在差分中允许一定程度的“粗糙”,您还可以使用-fuzz 5%
来允许图像中的细微差异。
检测的边界框的另一方式是squidge的差分图像,直到它是一个高大的图像,只有一个像素宽,这样的:
convert diff.jpg -scale 1x! -threshold 1% t.jpg
得到的图像如下:
现在,如果将输出转换为文本格式,您可以很容易地找到第一个白色像素(在程序中,您不会这样做 - 您会写一个循环代替 - 但我是示出的概念在这里):
convert diff.jpg -scale 1x! -threshold 1% txt: | grep -m1 white
0,176: (255,255,255) #FFFFFF white
的grep -m1 white
查找具有在它white
第一行,然后停止寻找(匹配被限制为1)。这表明白色像素的第一行是176 - 与上面的红色框相比。现在我们可以找到最后一个白色像素,使用:
convert diff.jpg -scale 1x! -threshold 1% txt: | grep white | tail -1
0,415: (255,255,255) #FFFFFF white
并且我们知道行415是边界框的底部。
现在你squidge图像的宽而扁的版本仅有1个像素高,并找到自己的边框的左,右极限:
convert diff.jpg -scale x1! -threshold 1% txt: | grep -m1 white
80,0: (255,255,255) #FFFFFF white
convert diff.jpg -scale x1! -threshold 1% txt: | grep white | tail -1
343,0: (255,255,255) #FFFFFF white
所以您边框的左右极限是80和343 - 根据红色矩形。
+1的详细示例,而不仅仅是文本。 – kkuilla 2014-10-29 09:58:36
- 1. AForge.net - BlobCounter获取2个图像之间的不同“区域”
- 2. 查找图像的区域
- 3. 如何在opencv中查找图像之间的重叠区域?
- 4. 查找表中作为列两个领域之间的区别
- 5. 查找两个图像之间的图像子集
- 6. 两个图像之间的重叠区域
- 7. 如何比较两个不同的地图视图区域,并找出它们之间的区别
- 8. 如何找到两个图像之间的区别?
- 9. 获取UIImage的两个不同图像部分的区域
- 10. 如何找到android中的两个区域之间的距离
- 11. 查找图像中的空白区域
- 12. Javascript - 查找图像的最暗区域
- 13. 查找Java中两个ArrayList之间的不同元素
- 14. 查找c#中两个整数范围之间的重叠区域
- 15. 查找两个字符串之间的多个区别
- 16. 填充三维图中两个线段之间的区域{rgl}
- 17. 两个查询之间的区别
- 18. 两个PostgreSQL查询之间的区别
- 19. 查找基因间区域
- 20. 图像应该如何处于两个按钮之间的区域?
- 21. 快速计算两个相似图像之间的“变脏”区域
- 22. 查找不同行中两次之间的时间差
- 23. 不同像素尺寸的两幅图像之间的插值
- 24. 两行之间的填充区域
- 25. MATLAB图像处理 - 查找图像的边缘和区域
- 26. 查找两个numpy结构阵列之间的区别
- 27. C库查找两个数组之间的区别
- 28. 查找Ruby中两个数组之间的唯一区别
- 29. 如何在jsp中查找两个日期之间的区别?
- 30. 轨连接两个表之间的查询与同类领域
您不指定使用的平台/语言。这样的像素比较任务通常可以支持每秒100 MBytes以上的速度,使用C或SSE优化的C.如果我理解您的问题,那么可能没有比蛮力更好的方法。 – 2014-10-28 13:33:17