Home > OS >  (-215:Assertion failed) corr.rows <= img.rows templ.rows - 1 && corr.cols <= img.cols temp
(-215:Assertion failed) corr.rows <= img.rows templ.rows - 1 && corr.cols <= img.cols temp

Time:10-09

I've run into issues with win32gui when trying to grab a real-time video stream of an application. I've seen I can use ImageGrab from PIL and based on this video Computer Screen Recording using Python & OpenCV I think I can use it instead of win32gui

I'm trying to learn python by writing a bot, the below code should grab images from a specified folder, load them into an array, converts them into a format OpenCV can use and then attempts to find any or all of them on my application window haystack

I can't find any details on google of the error I'm getting:

C:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips>C:/Users/coyle/AppData/Local/Programs/Python/Python39/python.exe c:/Users/coyle/OneDrive/froggy-pirate-master/avoidShips/avoidships4.py
Traceback (most recent call last):
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 41, in <module>
    loadImages()
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 22, in loadImages
    return matchTemplate(image_list)
  File "c:\Users\coyle\OneDrive\froggy-pirate-master\avoidShips\avoidships4.py", line 32, in matchTemplate
    result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
cv2.error: OpenCV(4.5.1) C:\Users\appveyor\AppData\Local\Temp\1\pip-req-build-wvn_it83\opencv\modules\imgproc\src\templmatch.cpp:588: error: (-215:Assertion failed) corr.rows <= img.rows   templ.rows - 1 && corr.cols <= img.cols   templ.cols - 1 in function 'cv::crossCorr'

And my code:

def loadImages():
    # Intialise empty array
    image_list = []
    # Get list of all images in directory
    directory = glob.glob(r"C:\Users\*.png")

    # Add images to image_list
    for img in directory:
        ship_img = cv.imread(img, 0)
        image_list.append(ship_img)
    return matchTemplate(image_list)

def matchTemplate(image_list):
    # Video Loop
    while True:
        haystack_img = ImageGrab.grab()
        haystack_img_np = np.array(haystack_img)
        haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
        
        # Object Detection
        for ships in image_list:
            needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)
            result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
            cv.imshow('Result', haystack)

            if cv.waitKey(1) == 27:
                break

        cv.destroyAllWindows()

loadImages()
matchTemplate()

As a test, I've tried doing the same thing using static images and it works so I'm not sure where I'm going wrong.

import cv2 as cv
import glob

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

for img in directory:
    ships_img = cv.imread(img, 0)
    image_list.append(ships_img)

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

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

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

CodePudding user response:

I can't test it but you simply try to load image which you already have in memory

You have

needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)

but image_list has already loaded image, not filenames.
Besides imread() needs sinlge filename but you try use it with some list converted to string.

You should use directly

needle_img = ships

I think it should be

def loadImages():
    # Intialise empty array
    image_list = []
    
    # Get list of all images in directory
    directory = glob.glob(r"C:\Users\*.png")

    # Add images to image_list
    for img in directory:
        ship_img = cv.imread(img, 0)  # <-- here you load all images
        image_list.append(ship_img)
        
    return image_list   # I preferr to send back data instead of running `matchTemplate`


def matchTemplate(image_list):
    # Video Loop
    while True:
        haystack_img = ImageGrab.grab()
        haystack_img_np = np.array(haystack_img)
        haystack = cv.cvtColor(haystack_img_np, cv.COLOR_BGR2GRAY)
        
        # Object Detection
        for ships in image_list:
            # you don't have to load images because you already have them in `image_list`
            #needle_img = cv.imread(str(image_list), cv.IMREAD_UNCHANGED)
            
            needle_img = ships
            
            result = cv.matchTemplate(haystack, needle_img, cv.TM_CCOEFF_NORMED)
            cv.imshow('Result', haystack)

            if cv.waitKey(1) == 27:
                break

        cv.destroyAllWindows()

# --- main ---

image_list = loadImages()
matchTemplate(image_list)

BTW:

In normal open(), read() you get error if it has problem to open or read file but in OpenCV imread() does't raise error when it can't load image but it gives None - but you don't check if you get None - and you don't know that there was problem to load it - and later when you try to use this value in next command (matchTemplate) then it shows error. But real problem was with imread()

  • Related