为什么 pygame 在我尝试将单个像素绘制到屏幕上以获取图像时崩溃
Why does pygame crash when I try to plot individual pixels to the screen for an image
我一直在编写一段代码来比较两个图像并告诉我它们是否相似,它还告诉我图像中哪些像素不同,之后它将它们绘制成 pygame 屏幕,以便我可以更清楚地看到图像的哪些部分在移动。唯一的问题是,似乎 pygame 无法处理它或其他东西,它崩溃了,没有出现错误。
代码:
import cv2
import pygame
from pygame.locals import *
lib = 'Map1.png'
lib2 = 'Map2.png'
lib3 = []
coordenatesx = []
coordenatesy = []
Read = list(cv2.imread(lib).astype("int"))
Read2 = list(cv2.imread(lib2).astype("int"))
counter = 0
for i in range(len(Read)):#y coords
for j in range(len(Read[i])):#x coords
blue = list(Read[i][j])[0]
green = list(Read[i][j])[1]
red = list(Read[i][j])[2]
blue2 = list(Read2[i][j])[0]
green2 = list(Read2[i][j])[1]
red2 = list(Read2[i][j])[2]
difference = (blue+green+red)-(blue2+green2+red2)
lib3.append(difference)
if difference <= 10 and difference >= -10:
counter+=1
coordenatesx.append(j)
coordenatesy.append(i)
if counter >= (i*j)*0.75:
print('They are similar images')
print('They are different by:', str((counter / (i * j)) * 100), '%')
else:
print('They are different')
print('They are different by:', str((counter / (i * j)) * 100), '%')
pygame.init()
screen = pygame.display.set_mode((500,500))
while 1:
screen.fill((20))
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
图片 1:
图片2:
Pygame 没有崩溃。您知道如何在不调用 pygame.event.get()
方法的情况下定义 Pygame window 会导致问题,对吗?好吧,当你把
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
进入本应不断调用 pygame.event.get()
方法的 while
循环,您正在显着减慢循环过程。
为了亲眼看到这一点,在循环中添加一个 print()
语句,看看它打印的速度有多慢:
while 1:
screen.fill((20))
print("Looping...")
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
一个解决方法是将 pygame.event.get()
调用 移动到 嵌套 for
循环 (以及 pygame.display.update()
如果您想查看更新,请致电):
while 1:
screen.fill((20))
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
使用cv2/OpenCV and NumPy. Compute the absolute difference of the images with numpy.absolute
. Sum the color channels and count the non-zero pixels with numpy.count_nonzero
:
import cv2
import numpy
Read = cv2.imread('Map1.png').astype("int")
Read2 = cv2.imread('Map2.png').astype("int")
diff = numpy.absolute(Read - Read2).astype("uint8")
gray = numpy.sum(diff, axis=2)
count = numpy.count_nonzero(gray)
print(f"{count} / {gray.size}")
如果您不想导入 NumPy:
diff = abs(Read - Read2)
gray = (diff[:,:,0] + diff[:,:,1] + diff[:,:,2])
diff = diff.astype("uint8")
count = sum([c > 0 for r in gray for c in r])
print(f"{count} / {gray.size}")
最小示例:
import cv2
import numpy
import pygame
from pygame.locals import *
lib = 'Map1.png'
lib2 = 'Map2.png'
Read = cv2.imread(lib).astype("int")
Read2 = cv2.imread(lib2).astype("int")
diff = numpy.absolute(Read - Read2).astype("uint8")
gray = numpy.sum(diff, axis=2)
count = numpy.count_nonzero(gray)
print(f"{count} / {gray.size}")
pygame.init()
screen = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()
def cv2ImageToSurface(cv2Image):
if cv2Image.dtype.name == 'uint16':
cv2Image = (cv2Image / 256).astype('uint8')
size = cv2Image.shape[1::-1]
if len(cv2Image.shape) == 2:
cv2Image = np.repeat(cv2Image.reshape(size[1], size[0], 1), 3, axis = 2)
format = 'RGB'
else:
format = 'RGBA' if cv2Image.shape[2] == 4 else 'RGB'
cv2Image[:, :, [0, 2]] = cv2Image[:, :, [2, 0]]
surface = pygame.image.frombuffer(cv2Image.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
diff_surf = cv2ImageToSurface(diff)
run = True
while run:
clock.tick(100)
screen.fill((20))
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
run = False
screen.fill(0)
screen.blit(diff_surf, diff_surf.get_rect(center = screen.get_rect().center))
pygame.display.update()
pygame.quit()
我一直在编写一段代码来比较两个图像并告诉我它们是否相似,它还告诉我图像中哪些像素不同,之后它将它们绘制成 pygame 屏幕,以便我可以更清楚地看到图像的哪些部分在移动。唯一的问题是,似乎 pygame 无法处理它或其他东西,它崩溃了,没有出现错误。
代码:
import cv2
import pygame
from pygame.locals import *
lib = 'Map1.png'
lib2 = 'Map2.png'
lib3 = []
coordenatesx = []
coordenatesy = []
Read = list(cv2.imread(lib).astype("int"))
Read2 = list(cv2.imread(lib2).astype("int"))
counter = 0
for i in range(len(Read)):#y coords
for j in range(len(Read[i])):#x coords
blue = list(Read[i][j])[0]
green = list(Read[i][j])[1]
red = list(Read[i][j])[2]
blue2 = list(Read2[i][j])[0]
green2 = list(Read2[i][j])[1]
red2 = list(Read2[i][j])[2]
difference = (blue+green+red)-(blue2+green2+red2)
lib3.append(difference)
if difference <= 10 and difference >= -10:
counter+=1
coordenatesx.append(j)
coordenatesy.append(i)
if counter >= (i*j)*0.75:
print('They are similar images')
print('They are different by:', str((counter / (i * j)) * 100), '%')
else:
print('They are different')
print('They are different by:', str((counter / (i * j)) * 100), '%')
pygame.init()
screen = pygame.display.set_mode((500,500))
while 1:
screen.fill((20))
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
图片 1:
图片2:
Pygame 没有崩溃。您知道如何在不调用 pygame.event.get()
方法的情况下定义 Pygame window 会导致问题,对吗?好吧,当你把
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
进入本应不断调用 pygame.event.get()
方法的 while
循环,您正在显着减慢循环过程。
为了亲眼看到这一点,在循环中添加一个 print()
语句,看看它打印的速度有多慢:
while 1:
screen.fill((20))
print("Looping...")
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
一个解决方法是将 pygame.event.get()
调用 移动到 嵌套 for
循环 (以及 pygame.display.update()
如果您想查看更新,请致电):
while 1:
screen.fill((20))
for l in range(len(coordenatesx)):
for v in range(len(coordenatesy)):
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
pygame.quit()
pygame.draw.rect(screen, (blue, red, green), pygame.Rect(coordenatesx[l], coordenatesy[v], 1, 1))
pygame.display.update()
使用cv2/OpenCV and NumPy. Compute the absolute difference of the images with numpy.absolute
. Sum the color channels and count the non-zero pixels with numpy.count_nonzero
:
import cv2
import numpy
Read = cv2.imread('Map1.png').astype("int")
Read2 = cv2.imread('Map2.png').astype("int")
diff = numpy.absolute(Read - Read2).astype("uint8")
gray = numpy.sum(diff, axis=2)
count = numpy.count_nonzero(gray)
print(f"{count} / {gray.size}")
如果您不想导入 NumPy:
diff = abs(Read - Read2)
gray = (diff[:,:,0] + diff[:,:,1] + diff[:,:,2])
diff = diff.astype("uint8")
count = sum([c > 0 for r in gray for c in r])
print(f"{count} / {gray.size}")
最小示例:
import cv2
import numpy
import pygame
from pygame.locals import *
lib = 'Map1.png'
lib2 = 'Map2.png'
Read = cv2.imread(lib).astype("int")
Read2 = cv2.imread(lib2).astype("int")
diff = numpy.absolute(Read - Read2).astype("uint8")
gray = numpy.sum(diff, axis=2)
count = numpy.count_nonzero(gray)
print(f"{count} / {gray.size}")
pygame.init()
screen = pygame.display.set_mode((500,500))
clock = pygame.time.Clock()
def cv2ImageToSurface(cv2Image):
if cv2Image.dtype.name == 'uint16':
cv2Image = (cv2Image / 256).astype('uint8')
size = cv2Image.shape[1::-1]
if len(cv2Image.shape) == 2:
cv2Image = np.repeat(cv2Image.reshape(size[1], size[0], 1), 3, axis = 2)
format = 'RGB'
else:
format = 'RGBA' if cv2Image.shape[2] == 4 else 'RGB'
cv2Image[:, :, [0, 2]] = cv2Image[:, :, [2, 0]]
surface = pygame.image.frombuffer(cv2Image.flatten(), size, format)
return surface.convert_alpha() if format == 'RGBA' else surface.convert()
diff_surf = cv2ImageToSurface(diff)
run = True
while run:
clock.tick(100)
screen.fill((20))
for event in pygame.event.get():
if event.type == QUIT or (event.type == KEYDOWN and event.key == K_ESCAPE):
run = False
screen.fill(0)
screen.blit(diff_surf, diff_surf.get_rect(center = screen.get_rect().center))
pygame.display.update()
pygame.quit()