2010-09-07 80 views
3

我想要减去两个图像。我的问题是cvSub()函数饱和。我想要做的是:通过使用opencv减去图像

1)将原始图像转换为灰度。

2)取灰度图像(值从0-255)。

3)减去图像(值从-255到255) - >使用cvSub()重新缩放的问题。

4)通过用0.5相乘并加入128

重新缩放我想从8位改变灰度图像,以16位的,但随后的一切变得更糟,并成为许多行代码和它到底没有解决。

+0

丑陋的解决方案只是循环显示图像,并且每个像素自己做一次。这基本上只是用C++翻译你的问题(甚至应该更短)。 – mb14 2010-09-07 08:55:43

回答

5

使用的OpenCV你可以执行以下操作:

  • 刻度既源图像(1和2)通过系数0.5。两个图像现在是在范围[0..127]
  • 移位图像1由128现在是在范围[128..255]
  • 减法图像2从图像1

这样,不需要范围转换,结果可以完全缩放到8位。前两个操作使用。

事情是这样的:

//... 
cvConvertScale(src1, tmp1, 0.5, 128); 
cvConvertScale(src2, tmp2, 0.5, 0); 
cvSub(tmp1, tmp2, dst); 

编辑:

要在信息丢失(精度)的评论,你是对的,但你使用整数运算分割时总是这样。在你的情况下扩大规模就是这样。简单地把它看作是把所有的位向右移动一个地方。所以最后一点信息就会丢失。

另一方面,应用操作的顺序也很重要。除以2,您将为每个像素引入一个舍入(或截断)错误0.5。如果在减去输入图像之前缩小它们,则舍入误差总计为1.0。这显示在结果图像中,因为与初始和Alexanders方法得到的结果相比,某些像素的偏移量为1。但这是简单解决方案的折衷方案,无需将图像扩展到16位或浮点。

见下面的例子:

实数:
(200 - 101)/ 2 = 99/2 = 49。5

亚历山大溶液(整数运算):
(200 - 101)/ 2 = 99/2 =

我的解决方案(整数运算):
(200/2) - (101/2)= 100 - 50 =

+1

感谢您的简单解决方案!它解决了! - 好主意先做缩放,然后减去图片。 – supergranu 2010-09-08 12:07:24

+0

唯一的问题是一个人丢失了信息。在这种情况下,最好选择Alexander Rafferty的版本。 – supergranu 2010-09-09 06:59:02

+0

你能告诉我你在哪里认为,你信息松动吗?你的意思是精确吗? – 2010-09-09 07:01:10

1

您需要将8bit转换为16bit。 然后将255添加到第一张图像,然后从中减去第二张图像。 然后除以2并转换回8位。

告诉我这是怎么回事,它应该工作。