Mar-25-2020, 07:28 AM
I was trying to make a bot that would work through image detection. So I did it, and it works, but I came to ask for suggestion on how I can improve my code to make things run more smoothly and efficiently. There's one main function, two utility functions, and then one more function for testing its efficiency. Here's the code:
Thanks in advance for any help with this.
from PIL import ImageGrab import time, cv2, random #Pre-sets FileNames = {"Main" : "Screenshot.png", "Level" : "Level.png", "Refresh" : "Refresh.png", "StartExercise" : "StartExercise.png", "Test" : "TestCapture.png"} #Util Functions def UpdatedImage(imageName, coords=None): ImageGrab.grab(coords).save(imageName, "PNG") return cv2.imread(imageName) def CheckPixels(pixel1, pixel2): if pixel1[0] == pixel2[0] and pixel1[1] == pixel2[1] and pixel1[2] == pixel2[2]: return True return False def CheckImages(originalImage, comparisonImage): #This function finds a pixel that matches the first pixel of the comparison Picture and then checks all the pixels around it until it has either identified it to be matching or not matching StartingPixel = comparisonImage[0][0] for row in range(0, len(originalImage)): pixelCount = -1 if row+len(comparisonImage) > len(originalImage): break for pixel in originalImage[row]: pixelCount += 1 if pixelCount+len(comparisonImage[0]) > len(originalImage[0]): break if CheckPixels(pixel, StartingPixel): matching = True columnOffset = 0 rowOffset = 0 while matching: while matching and columnOffset < len(comparisonImage[0])-1 and rowOffset < len(comparisonImage)-1: columnOffset += 1 if not CheckPixels(comparisonImage[rowOffset][columnOffset], originalImage[row+rowOffset][pixelCount+columnOffset]): matching = False if columnOffset == len(comparisonImage[0])-1 and matching: rowOffset += 1 offset = 0 if rowOffset == len(comparisonImage)-1: return True, (pixelCount-columnOffset, row-rowOffset) return False, None def Testrun(accuracy): TimeDatabase = [] FalseCount = 0 for x in range(0, accuracy): print("Preparing images...") ScreenshotData = UpdatedImage(FileNames["Main"]) TestImageData = UpdatedImage(FileNames["Test"], (random.randint(0, 525), random.randint(0, 325), random.randint(526, 1050), random.randint(325, 650))) print("Testing commenced...") startingTime = time.time() success, _ = CheckImages(ScreenshotData, TestImageData) if not success: FalseCount += 1 totalTime = time.time()-startingTime TimeDatabase.append(totalTime) print("Testing number %s was a success: %s\ntotal time applied: %s\n" %(x+1, success, totalTime)) AverageTime = 0 for t in TimeDatabase: AverageTime += t AverageTime /= len(TimeDatabase) MinTime = min(TimeDatabase) MaxTime = max(TimeDatabase) print("Testing is now complete. The average time for each run was %s\nThe minimum time was %s\nThe maximum time was %s\n%s tests were found to be false" %(AverageTime, MinTime, MaxTime, FalseCount)) if __name__ == "__main__": #Exercise() Testrun(100)I ran it on my background which is colorful and probably made it easier for the program. The background was also changing every ten seconds hence the 6 failed tests. This is the output (Not including the individual prints of each test).
Output:Testing is now complete. The average time for each run was 0.33153117656707765
The minimum time was 0.006017446517944336
The maximum time was 5.9415600299835205
6 tests were found to be false
One last thing, are there any efficient methods to recognizing photos that are enlarged from the original? For example, if I took a screenshot, snipped a part of it, enlarged that part a little bit, and the bot could still recognize the picture from the screenshot.Thanks in advance for any help with this.