【问题标题】:Template Matching using PyOpenCl使用 PyOpenCl 进行模板匹配
【发布时间】:2020-05-31 06:48:56
【问题描述】:

我正在使用 opencl 处理图像处理中更复杂的方面。现在我尝试的是模板匹配,我得到了一些结果,但不确定它是否正确。反正我觉得模板是匹配的。。这里是我用的脚本和图片。。。

python 文件:

import pyopencl as cl
import numpy as np
from PIL import Image
from time import time
import cv2


def getAssets(platform,device):
    plat = cl.get_platforms()[platform]
    dev = plat.get_devices()[device]
    ctx = cl.Context([dev])
    q = cl.CommandQueue(ctx)
    return ctx,q

def getKernel():
    string = "F:\Image processing\Template\matchTemplate.c"
    krnl = open(string).read()
    return krnl

def execution(image,template):

    cntx,queue = getAssets(0,0)

    img = np.asarray(image).astype(np.int32)
    temp = np.asarray(template).astype(np.int32)

    mf = cl.mem_flags

    inp = cl.Buffer(cntx,mf.READ_ONLY | mf.COPY_HOST_PTR,hostbuf=img)
    tmp = cl.Buffer(cntx,mf.READ_ONLY | mf.COPY_HOST_PTR,hostbuf=temp)
    out = cl.Buffer(cntx,mf.WRITE_ONLY,img.nbytes)

    task = cl.Program(cntx,getKernel()%(x,y)).build()

    val = task.matchTmp(queue,img.shape,None,inp,tmp,out)

    output = np.empty_like(img)

    cl.enqueue_copy(queue,output,out)

    output = output.astype(np.uint8)
    print(output,output.min(),output.max())
    return np.array(output)


def showResult(image,template):
    result = execution(image,template)
    result = Image.fromarray(result)
    result.show()


if __name__ == '__main__':
    image = cv2.imread("F:\Image processing\Template\cam.jpg",0)
    template = cv2.imread("F:\Image processing\Template\Template.jpg",0)
    global x,y
    x = image.shape[1]
    y = image.shape[0]
    # print(image.shape)
    # cv2.imshow("image",template)
    # cv2.waitKey(0)
    showResult(image,template)

内核文件:

#pragma OPENCL EXTENSION cl_khr_fp64 : enable
__kernel void matchTmp(__global int *inp,__global int *tmp,__global int *out){
      int j = get_global_id(1);
      int i = get_global_id(0);
      int x = get_global_id(3);
      int y = get_global_id(2);
      int Iwidth = %d;
      int rown = %d;
      int w = 48;
      int r= 48;
      int value = 0,value1,value2,value3;

          value1 = value1 + half_powr((tmp[x*48 + y] - inp[(i+x)*Iwidth + (j+y)]),2);
          value2 = value2 + half_powr(tmp[x*48 + y],2);
          value3 = value3 + half_powr(inp[(i+x)*Iwidth + (j+y)],2);
          value = (value1/half_sqrt(value2*value3))*50;


          value = (value < 0   ? 0   : value);
          value = (value > 255 ? 255 : value);
          out[i*Iwidth + j] = value;

  }

图片: The image used

模板: the template to be matched

结果: this is the result

我使用了method=CV_TM_SQDIFF_NORMED,如本网站OpenCV doc 所示。我确实在物体附近获得了很高的价值,但是为什么其他东西都是黑色的?实际结果应该类似于here... 任何人都可以帮助我吗?

【问题讨论】:

  • 我怀疑是因为模板与天空的匹配不是很好,所以你会得到非常低的相关分数,因此非常暗。
  • 好吧...但是你能解释一下为什么图像中模板的中心值最高吗?它应该在模板的左上角...直到我在其他示例中观察到的...
  • 峰值似乎在 240,210 左右。那是你拥有最大亮点的地方。大多数模板匹配返回模板左上角位于最佳匹配处的最佳匹配。所以大约是220,200。但我不知道你的 pyopencl 或你的代码。所以它可能会返回模板中心在最佳匹配位置的坐标,这确实对应于大约 240,210 处的亮点。所以看起来它工作正常。
  • @fmw42 你能给我一些关于模板匹配是如何工作的参考资料吗……比如一些伪代码、文档、算法等……这对我的其他图像有很大帮助,结果不一样...
  • 谷歌搜索。你会发现很多参考资料。例如:opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/… 和 researchgate.net/figure/…

标签: python-3.x opencl pyopencl template-matching opencv-python


【解决方案1】:

我不知道 pyopencl。但这里是 Python/OpenCV 中的模板匹配演示,用于显示输入图像中最佳匹配和 matchTemplate() 产生的相关图像中的最佳匹配的对应关系。

模板一次在图像上移动一个像素,然后将模板与图像中的当前位置逐个像素地进行比较,然后计算一个度量分数并将其记录在新图像中。所以输出图像中的位置对应于模板在输入图像上移动时的左上角。

输入:

模板:

import cv2
import numpy as np

# read image
img = cv2.imread('airplane.jpg')

# read template
tmplt = cv2.imread('airplane_tail.jpg')
hh, ww = tmplt.shape[:2]

# do template matching
# move template across image 1 pixe shift at a time and compute the correlation metric at each shift position as an image
corrimg = cv2.matchTemplate(img,tmplt,cv2.TM_CCOEFF_NORMED)

# get location of best match corresponding to the upper left corner of template from the brightest spot in corrimg
min_val, max_val, min_loc, max_loc = cv2.minMaxLoc(corrimg)
max_val_ncc = '{:.3f}'.format(max_val)
print("normalize_cross_correlation: " + max_val_ncc)
xx = max_loc[0]
yy = max_loc[1]
print('x_match_loc =',xx,'y_match_loc =',yy)

# draw template bounds in red onto img and corrimg scaled to 8-bit range
result1 = img.copy()
result2 = (255*corrimg).clip(0,255).astype(np.uint8)
result2 = cv2.merge([result2,result2,result2])
cv2.rectangle(result1, (xx, yy), (xx+ww, yy+hh), (0, 0, 255), 1)
cv2.rectangle(result2, (xx, yy), (xx+ww, yy+hh), (0, 0, 255), 1)

# save results
cv2.imwrite('airplane_template_match_location.jpg', result1)
cv2.imwrite('airplane_correlation_image_location.jpg', result2)

# show images
cv2.imshow('image', img)
cv2.imshow('template', tmplt)
cv2.imshow('result1', result1)
cv2.imshow('result2', result2)
cv2.waitKey(0)
cv2.destroyAllWindows()


匹配输入图像中的位置:

在相关图像中匹配位置:

文本输出:

normalize_cross_correlation: 0.996
x_match_loc = 216 y_match_loc = 190


【讨论】:

  • 好的...这给了我结果,没有问题。我想要的是,看看我的结果图像,我只是在模板附近有一些高值,就是这样。但是我应该怎么做才能得到与opencv获得的相同的结果图像(相关矩阵)?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-29
  • 2015-04-14
  • 2015-05-18
  • 1970-01-01
  • 2016-03-03
  • 2012-01-07
相关资源
最近更新 更多