1

This code takes a screenshot of the screen and then looks for a given object on the screen, by comparing it to the template given, and then counts how many times the object is found. This can be seen below with the mario coins picture in which the program will identify each mario coin and then count how many there are total. My problem is that I would like for the program to continue counting the coins while running, so that if a coin is added or subtracted on the screen the program updates the count number.

Ex: Counts 19 coins, Counts 19 coins, Counts 19 coins, (Two coins added), Counts 21 coins, Counts 21 coins etc.

import cv2 as cv2
import numpy
import pyautogui

# Takes a screen shot and saves the file in the specified location
loc1 = (r'Capture.png')
pyautogui.screenshot(loc1)

# Reads the screen shot and loads the image it will be compared too
img_rgb = cv2.imread(loc1)
count = 0
n = 0

while n < 5:
    # Reads the file
    template_file_ore = r"mario.png"
    template_ore = cv2.imread(template_file_ore)
    w, h = template_ore.shape[:-1]

    # Compares screen shot to given image, gives error thresh hold
    res = cv2.matchTemplate(img_rgb, template_ore, cv2.TM_CCOEFF_NORMED)
    threshold = 0.80
    loc = numpy.where(res >= threshold)

    # Puts red box around matched images and counts coins
    for pt in zip(*loc[::-1]):
        cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
        count = count + 1

        print(count)
    n = n + 1

Mario Picture

Christoph Rackwitz
  • 11,317
  • 4
  • 27
  • 36
ITM007
  • 117
  • 2
  • 9

3 Answers3

1

How about this,You can use a variable outside while-loop that stores the currently counted coins, then rerun(read a different mario_image) count again and compare if there is a difference between to variables if there is update.

currently_counted_coins =0 #init
...
#after for loop
difference = count-currently_counted_coins # if difference <0 coins removed else added
#update
currently_counted_coins += difference # to keep a total number of coins  
TassosK
  • 293
  • 3
  • 16
  • I tried this, and it works if i stop and restart the code. But I would like it to continue checking for new "coins" as long as the code is running. The problem is that the "for" loop is ignored one the 2,3,4 etc iterations. It treats the "for" loop as invisible after running it once. – ITM007 Mar 12 '19 at 00:54
  • that's because you 're reading one image per execution you need to have a loop to read new images(to check for matching) and update. For example you can have a list with images and iterate through and compare[ Update input data]. – TassosK Mar 12 '19 at 01:37
  • I'm relatively new to python and only somewhat understand what you are explaining. Do you think you could show an example with the code as you did in your first post? – ITM007 Mar 12 '19 at 02:34
1

I ended up figuring it out just have to rerun the whole code in the "for" loop, as seen below.

    import cv2 as cv2
    import numpy
    import pyautogui

    # Takes a screen shot and saves the file in the specified location
    loc1 = (r'Capture.png')
    pyautogui.screenshot(loc1)

    # Reads the screen shot and loads the image it will be compared too
    img_rgb = cv2.imread(loc1)
    count = 0
    n = 0

    while n < 20:
        # Reads the file
        template_file_ore = r"mario.png"
        template_ore = cv2.imread(template_file_ore)
        w, h = template_ore.shape[:-1]

        # Compares screen shot to given image, gives error thresh hold
        res = cv2.matchTemplate(img_rgb, template_ore, cv2.TM_CCOEFF_NORMED)
        threshold = 0.80
        loc = numpy.where(res >= threshold)

        # Puts red box around matched images and counts coins
        for pt in zip(*loc[::-1]):
            loc1 = (r'Capture.png')
            pyautogui.screenshot(loc1)

         # Reads the file
            template_file_ore = r"mario.png"
            template_ore = cv2.imread(template_file_ore)
            w, h = template_ore.shape[:-1]

         # Compares screen shot to given image, gives error thresh hold
            res = cv2.matchTemplate(img_rgb, template_ore, cv2.TM_CCOEFF_NORMED)
            threshold = 0.80
            loc = numpy.where(res >= threshold)

          # Reads the screen shot and loads the image it will be compared too
            img_rgb = cv2.imread(loc1)
            cv2.rectangle(img_rgb, pt, (pt[0] + w, pt[1] + h), (0, 0, 255), 2)
            count = count + 1

            print(count)
        n = n + 1
ITM007
  • 117
  • 2
  • 9
  • that works too.Don't forget thumbs up for the answers, and also a tip use the google more wisely it'll become your best advisor ;) – TassosK Mar 13 '19 at 14:28
1

there are many ways to do that, For example create a list with images[screenshots] you want to check for matching and put all your code inside a for loop iteration through list items.

list_images = ['image1.png','image2.png',..]

for img in list_images:
  # here put your code 
  img_to_be_checked = cv2.imread(img)
  # continue with your code in the while loop

to create the list of images you can take a few snapshots and store them with a name or use your code to take the snapshot multi times but you have to change the desktop -image before you take a new snapshot to see any differences. You could use a timestamp to take snaps periodically so you have time to change the input image. the easiest way is to pre-save screenshots and then read them as I saw you on the above code.

TassosK
  • 293
  • 3
  • 16