使用OpenCV和Python转换类函数以遍历多个图像 [英] Converting a class function to iterate through multiple images with OpenCV and Python

查看:61
本文介绍了使用OpenCV和Python转换类函数以遍历多个图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用OpenCV实时检测图像.这适用于单个图像.我正在尝试更新脚本以一次处理多个图像,最终目的是一次检测屏幕上的几个不同元素,并在它们周围绘制矩形,同时返回图像的中心点以在其他地方使用./p>

我已经尽力从 main.py 文件中传递图像并开始搜索.

 #加载源图像source_images = glob.glob(r'C:\\\\\\\\ *.jpg')#执行搜索搜索=搜索(source_images) 

我似乎无法将 loaded_images 传递到我的 find 函数中.我尝试在Class属性和构造函数中定义 loaded_images ,但均无法正常工作,并给我错误 NameError:未定义名称'loaded_images'

  class搜索:# 特性needle_img =无needle_w = 0needle_h = 0方法=无#空列表存储源图像#loaded_images = []< -------------------------------------------------#构造函数定义__init __(self,source_images,method = cv.TM_CCOEFF_NORMED):#设置加载图像时使用的方法self.method =方法#空列表存储源图像#loading_images = []< -------------------------------------------------#将针图像加载到loaded_iamges数组中对于source_images中的img:self.needle_img = cv.imread(img,cv.IMREAD_UNCHANGED)loading_images.append(self.needle_img)返回self.loaded_images< --------------------------------def查找(self,haystack_img,threshold = 0.5,debug_mode = None):对于loading_images中的img:#保存针图像的尺寸self.needle_w = self.needle_img.shape [1]self.needle_h = self.needle_img.shape [0]#运行OpenCV算法结果= cv.matchTemplate(干草堆_img,self.needle_img,self.method) 

我还编写了下一个代码段,该段与屏幕快照(而不是实时图像)上的多个图像匹配,以尝试找出我做错了什么.它帮助我走了这么远,但我现在陷入困境.

 #加载源图像source_images = glob.glob(r'C:\\\\\\\\ *.jpg')#空列表存储源图像loading_images = []对于source_images中的img:needle_img = cv.imread(img,0)loading_images.append(needle_img)haystack_img = cv.imread(r'C:\\\\\\ both.jpg')haystack_img = cv.cvtColor(haystack_img,cv.COLOR_BGR2GRAY)#loop匹配对于loading_images中的针头:#保存针图像的尺寸(tH,tW)=针形.[:2]结果= cv.matchTemplate(干草堆_img,针,cv.TM_CCOEFF)min_val,max_val,min_loc,max_loc = cv.minMaxLoc(结果)top_left = max_locbottom_right =(top_left [0] + tW,top_left [1] + tH)cv.rectangle(haystack_img,top_left,bottom_right,255,2)cv.imshow('结果',haystack_img)cv.waitKey(0) 

解决方案

直接将加载的图像传递到以下位置即可:

  class搜索:定义__init __(self,source_images,method = cv.TM_CCOEFF_NORMED):#设置加载图像时使用的方法self.method =方法def查找(自我,haystack_img,loaded_images,阈值= 0.5,debug_mode =无):对于loading_images中的img:#保存针图像的尺寸self.needle_w = self.needle_img.shape [1]self.needle_h = self.needle_img.shape [0]#您一次又一次地覆盖相同的needle_w和needle_h变量...#运行OpenCV算法结果= cv.matchTemplate(干草堆_img,self.needle_img,self.method) 

或将加载的图像存储在字段中:

  class搜索:定义__init __(self,source_images,method = cv.TM_CCOEFF_NORMED):#设置加载图像时使用的方法self.method =方法self.loaded_images = []#将针图像加载到loaded_iamges数组中对于source_images中的img:needle_img = cv.imread(img,cv.IMREAD_UNCHANGED)self.loaded_images.append(needle_img)def查找(self,haystack_img,threshold = 0.5,debug_mode = None):对于self.loaded_images中的img:#保存针图像的尺寸self.needle_w = self.needle_img.shape [1]self.needle_h = self.needle_img.shape [0]#您一次又一次地覆盖相同的needle_w和needle_h变量...#运行OpenCV算法结果= cv.matchTemplate(干草堆_img,self.needle_img,self.method) 

通常,您需要了解范围和类变量与实例变量之间的区别.另外,在这里我没有看到为什么只需要一个类的实例时为什么需要类,所以一般来说请阅读有关OOP的内容.

I'm using OpenCV to detect images in real-time. This is working with single images. I'm trying to update the script to work with multiple images at once with the end goal to be to detect a few different elements on the screen at once and draw rectangles around them while returning the centre points of the images for use elsewhere.

I've gotten as far as passing the images in from my main.py file and initiating the search.

# load source images
source_images = glob.glob(r'C:\\\\\\\*.jpg')

# perform the search
search = Search(source_images)

I can't seem to pass loaded_images into my find function. I've tried defining loaded_images in the Class properties and within the constructor but neither work and give me the error NameError: name 'loaded_images' is not defined

class Search:

    # properties
    needle_img = None
    needle_w = 0
    needle_h = 0
    method = None

    # empty list to store the source images
    #loaded_images = [] <-------------------------------------------------

    # constructor                                        
    def __init__(self, source_images, method=cv.TM_CCOEFF_NORMED):
                     
        # Set the method we're using when we load the image 
        self.method = method

        # empty list to store the source images
        # loaded_images = [] <-------------------------------------------------
        
        # load the needle image into loaded_iamges array
        for img in source_images:
            self.needle_img = cv.imread(img, cv.IMREAD_UNCHANGED)
            loaded_images.append(self.needle_img)

            return self.loaded_images <--------------------------------

    def find(self, haystack_img, threshold=0.5, debug_mode=None):
        
        for img in loaded_images:
            # Save the dimensions of the needle images
            self.needle_w = self.needle_img.shape[1]
            self.needle_h = self.needle_img.shape[0]
            
            # run the OpenCV algorithm
            result = cv.matchTemplate(haystack_img, self.needle_img, self.method)

I also wrote this next code segment that matches multiple images on a screenshot rather than a real-time image to try and figure out what I was doing wrong. It's helped me get this far but I am now stuck.

# load source images
source_images = glob.glob(r'C:\\\\\\\*.jpg')
# empty list to store the source images
loaded_images = []

for img in source_images:
    needle_img = cv.imread(img, 0)
    loaded_images.append(needle_img)

haystack_img = cv.imread(r'C:\\\\\\both.jpg')
haystack_img = cv.cvtColor(haystack_img, cv.COLOR_BGR2GRAY)

#loop for matching
for needles in loaded_images:
    
    #save the dimensions of the needle images
    (tH, tW) = needles.shape[:2]
    result = cv.matchTemplate(haystack_img, needles, cv.TM_CCOEFF)
    min_val, max_val, min_loc, max_loc = cv.minMaxLoc(result)
    top_left = max_loc
    
    bottom_right = (top_left[0] + tW, top_left[1] + tH)
    cv.rectangle(haystack_img, top_left, bottom_right, 255, 2)

cv.imshow('Result', haystack_img)
cv.waitKey(0)

解决方案

Either pass loaded images directly to find:

class Search:              
    def __init__(self, source_images, method=cv.TM_CCOEFF_NORMED):
                     
        # Set the method we're using when we load the image 
        self.method = method

    def find(self, haystack_img, loaded_images, threshold=0.5, debug_mode=None):
        for img in loaded_images:
            # Save the dimensions of the needle images
            self.needle_w = self.needle_img.shape[1]
            self.needle_h = self.needle_img.shape[0]
            # you are overwriting the same needle_w and needle_h variable over and over again in a loop...
            
            # run the OpenCV algorithm
            result = cv.matchTemplate(haystack_img, self.needle_img, self.method)

Or store loaded images in field:

class Search:                                    
    def __init__(self, source_images, method=cv.TM_CCOEFF_NORMED):
        # Set the method we're using when we load the image 
        self.method = method

        self.loaded_images = [] 
        # load the needle image into loaded_iamges array
        for img in source_images:
            needle_img = cv.imread(img, cv.IMREAD_UNCHANGED)
            self.loaded_images.append(needle_img)

    def find(self, haystack_img, threshold=0.5, debug_mode=None):
        for img in self.loaded_images:
            # Save the dimensions of the needle images
            self.needle_w = self.needle_img.shape[1]
            self.needle_h = self.needle_img.shape[0]
            # you are overwriting the same needle_w and needle_h variable over and over again in a loop...
            
            # run the OpenCV algorithm
            result = cv.matchTemplate(haystack_img, self.needle_img, self.method)

In general you need to learn about scopes and difference between class and instance variables. Also I don't see here why you would need class when you would probably only have one instance of it, so maybe read about OOP in general.

这篇关于使用OpenCV和Python转换类函数以遍历多个图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆