Python OpenCV没有';在同一个图像上不能给出相同的输出

Python OpenCV没有';在同一个图像上不能给出相同的输出,python,numpy,opencv,Python,Numpy,Opencv,我正在尝试创建一个程序来检查两个图像是否相同。我有以下代码,这两个图像都会执行: img=cv2.imread('canvas.png') 掩码=np.0(img.shape[:2],np.uint8) bgdModel=np.zero((1,65),np.float64) fgdModel=np.zero((1,65),np.float64) rect=(70,70300250) cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT

我正在尝试创建一个程序来检查两个图像是否相同。我有以下代码,这两个图像都会执行:

img=cv2.imread('canvas.png')
掩码=np.0(img.shape[:2],np.uint8)
bgdModel=np.zero((1,65),np.float64)
fgdModel=np.zero((1,65),np.float64)
rect=(70,70300250)
cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_rect)
mask2=np.where((mask==2)|(mask==0),0,1).astype('uint8')
img=img*mask2[:,:,np.newaxis]
img=img[84:191,84:203]
计数=1
cv2.imwrite(“tmp/”+str(count)+.png”,img)
第一次运行时,我得到以下输出: . 经过一段时间~7秒后,我使用完全相同的图像执行此操作,并得到以下输出:。我再试了一次,再次得到了不同的输出:

我试图检查图像是否与内容相同,但我无法使其正常工作。我使用Stackoverflow上的以下代码检查相似性:

def与之类似(图1、图2):
返回image1.shape==image2.shape和not(np.bitwise\uxor(image1,image2.any())
当用第二个图像检查第一个图像时,返回false。我怎样才能做到这一点

谢谢你抽出时间

==编辑====

这是

==编辑2====

在看了@Rotem他们的答案后,我尝试了一下,但仍然显示出一点细微的差异,上面的函数返回
False
on:

cv2。grabCut
不会给出确定性结果,因为grabCut算法使用内置的随机性

根据:

这用于在像素标签上构造马尔可夫随机字段

在执行
cv2.grabCut
之前,您可以通过重置OpenCV随机生成器的种子来避免随机性:

cv2.setRNGSeed(0)
下面是一个代码示例:

for count in range(10):
    cv2.setRNGSeed(0)
    img = cv2.imread('canvas.png')
    mask = np.zeros(img.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (70,70,300,250)
    cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    img = img*mask2[:,:,np.newaxis]
    img = img[84:191, 84:203]
    cv2.imwrite(str(count)+".png", img)

更新: 您可以使用以下循环来比较图像:

# Verify that all images are the same
for count in range(10):
    im = cv2.imread(str(count)+".png")
    is_same = is_similar(im, img)
    if not is_same:
        print('Images are not the same, and it is strange!')
在我的机器里,它们都是一样的


完整代码:

import cv2
import numpy as np

# Disable OpenCL and disable multi-threading.
cv2.ocl.setUseOpenCL(False)
cv2.setNumThreads(1)


def is_similar(image1, image2):
    return image1.shape == image2.shape and not(np.bitwise_xor(image1,image2).any())

for count in range(10):
    cv2.setRNGSeed(0)
    img = cv2.imread('canvas.png')
    mask = np.zeros(img.shape[:2],np.uint8)
    bgdModel = np.zeros((1,65),np.float64)
    fgdModel = np.zeros((1,65),np.float64)
    rect = (70,70,300,250)
    cv2.grabCut(img,mask,rect,bgdModel,fgdModel,5,cv2.GC_INIT_WITH_RECT)
    mask2 = np.where((mask==2)|(mask==0),0,1).astype('uint8')
    img = img*mask2[:,:,np.newaxis]
    img = img[84:191, 84:203]
    cv2.imwrite(str(count)+".png", img)


# Verify that all images are the same
for count in range(10):
    im = cv2.imread(str(count)+".png")
    is_same = is_similar(im, img)
    if not is_same:
        print('Images are not the same, and it is strange!')

cv2.grabCut()
中有一个随机因素。在初始标记后,使用高斯混合模型检测前景和背景。更多信息请参阅grabcut引用的论文


正是由于这种随机性,你看到了不同的结果。你应该考虑使用一些降噪技术,比如形态学运算(<代码> CV2,腐蚀())/代码>和<代码> CV2..DistAuter()/代码>来处理这个问题。

你能发布“代码> >画布吗?PNG ,使问题重现吗?”RoTEM补充说,谢谢你的回答!我已经试过了
xv.setRNGSeed(0)
,但它仍然返回了两个稍有不同的图像,而我用来检查图像是否相同的函数并不喜欢。检查问题更新,有什么问题吗?我添加了一个循环来比较结果(更新了我的帖子)。在我的机器中,所有图像都是相同的。这可能是因为在你的系统中,仅仅依靠随机发生器的种子是不够的。有些情况下,浮点运算由于舍入错误而产生不同的结果(GPU执行等并行计算中的常见问题,但CPU多线程也是不确定的)。我不能说这里是否是这样。您可以尝试禁用OpenCL和多线程:
cv2.ocl.setUseOpenCL(False)
cv2.setNumThreads(1)