使用opencv减去图像

时间:2010-09-07 08:39:07

标签: c++ opencv

我想减去两张图片。我的问题是cvSub() - 函数饱和。我想做的是:

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

2)拍摄灰度图像(值从0到255)。

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

4)通过乘以0.5并添加128来重新缩放。

我想过将灰度图像从8位更改为16位,但随后一切都变得更糟,它变成了许多行代码,最终它没有用完。

2 个答案:

答案 0 :(得分:5)

使用openCV可以执行以下操作:

  • 将源图像(1和2)缩放0.5倍。两个图像现在都在[0..127]
  • 范围内
  • 将图像1移动128.现在它在[128..255]
  • 范围内
  • 从图像1中减去图像2

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

这样的事情:

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

修改

对于丢失信息(精确度)的评论,你是对的,但你总是在使用整数数学进行划分时。在你的情况下缩放就是这样。简单地认为它将所有位向右移动一个位置。所以最后一点信息丢失了。

另一方面,应用操作的顺序也很重要。除以2,为每个像素引入0.5的舍入(或截断)误差。如果在减去输入图像之前缩放它们,则舍入误差总计为1.0。这会在结果图像中显示为一些像素偏离1,而初始和Alexanders方法的结果则相反。但这是更简单的解决方案的权衡,而不将图像扩展到16位或浮点。

见这个例子:

实数:
(200 - 101)/ 2 = 99/2 = 49.5

Alexanders解决方案(整数数学):
(200 - 101)/ 2 = 99/2 = 49

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

答案 1 :(得分:1)

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

告诉我这是怎么回事,它应该有效。