当我尝试将单个像素绘制到屏幕上以获得图像时,为什么 pygame 会崩溃

发布于 2025-01-13 17:06:38 字数 2001 浏览 0 评论 0原文

我一直在编写一段代码,它比较两个图像并告诉我它们是否相似,它还告诉我图像中哪些像素不同,之后它将它们绘制到 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()

image1:

在此处输入图像描述

image2:

在此处输入图像描述

I've been working on a piece of code that compares two images and tells me if they are similar, it also tells me which pixels are different in the image, after this it plots them into a pygame screen so that I can see which parts of the image are moving more clearly. The only problem is that it seems as if pygame cannot handle it or something and it crashes, no errors appear.

code:

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()

image1:

enter image description here

image2:

enter image description here

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

原来分手还会想你 2025-01-20 17:06:38

Pygame 没有崩溃。您知道在不调用 pygame.event.get() 方法的情况下定义 Pygame 窗口会导致问题吗?好吧,当您放入

    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()

Pygame didn't crash. You know how defining a Pygame window without calling the pygame.event.get() method would cause problems, right? Well, when you put

    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))

into the while loop that's supposed to constantly call the pygame.event.get() method, you are dramatically slowing down the looping process.

To see this with your eyes, add a print() statement into the loop, and see how slow it prints:

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()

One fix is to move the pygame.event.get() call into the nested for loop (as well as the pygame.display.update() call if you want to see the updating):

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()
披肩女神 2025-01-20 17:06:38

使用 cv2/OpenCVNumPy。使用 numpy.absolute。对颜色通道求和并使用 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()

Use 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}")

If you don't want to import 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}")

Minimal example:

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()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文