如果像素小于特定值,如何遍历 pygame 3d surfarray 并更改像素的单独颜色?
How to iterate through a pygame 3d surfarray and change the individual color of the pixels if they're less than a specific value?
我正在尝试迭代 pygame 3d surfarray,更具体地说 pygame.surfarray.array3d("your image")
。我正在接收从我的网络摄像头捕获的视频,然后将它们转换为 3d 数组,然后使用此代码将其显示到我的 window 上。
def cameraSee(self):
while True:
self.cam.query_image()
self.image = self.cam.get_image()
self.imageArr = pygame.surfarray.array3d(self.image)
pygame.surfarray.blit_array(self.screen,self.imageArr)
os.system("clear")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
我的问题是我试图让我的相机只显示蓝色量大于 200(范围从 0 - 255)的任何像素,并将所有其他像素的颜色值更改为 0。我'我已经尝试对数组使用 if 语句,但我收到一条错误消息,指出我应该使用 any()
或 all()
.
我所有的代码:
try:
import pygame
import pygame.camera
import pygame.surfarray
import numpy
import os
import sys
import time
except:
print("there was an error importing modules...")
os.system("espeak 'there, was, an, error, importing, modules'")
time.sleep(2)
class aaiVision(object):
def __init__(self,screen,cam,image,imageArr):
self.screen = screen
self.cam = cam
self.image = image
self.imageArr = imageArr
def startUp(self):
os.system("espeak 'eh, eh, i, vision, initializing'")
pygame.init()
pygame.camera.init()
time.sleep(1)
os.system("espeak 'Vision, initialized'")
camList = pygame.camera.list_cameras()
print(camList)
time.sleep(1)
os.system("espeak 'cameras, found, %s'" % str(len(camList)))
time.sleep(1)
self.screen = pygame.display.set_mode((640,480))
time.sleep(0.5)
self.cam = pygame.camera.Camera("/dev/video0",(640,480),"YUV")
time.sleep(0.5)
self.cam.start()
os.system("espeak 'eh, eh, i, vision, online'")
def cameraSee(self):
while True:
self.cam.query_image()
self.image = self.cam.get_image()
self.imageArr = pygame.surfarray.array3d(self.image)
pygame.surfarray.blit_array(self.screen,self.imageArr)
os.system("clear")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
eyesAwake = aaiVision('', '', '', '')
if __name__ == "__main__":
eyesAwake.startUp()
eyesAwake.cameraSee()
抱歉出现了一些缩进错误,我不确定如何使用文本代码块 XD
我不确定是否有效,但请尝试一下
outArr = np.array( [[w if w[2] > 200 else np.zeros(3) for w in h] for h in self.imageArr], dtype='uint8')
想法是三维数组具有三个索引,第一个描述位置的高度,第二个描述位置的宽度,最后一个描述像素的颜色。因此,如果颜色列表的第三个条目(对应于蓝色)大于 200,则比较颜色列表的列表理解。如果不是这种情况,则重置所有颜色值。
与其遍历列表理解中的像素(这在 python 中肯定会很慢),然后将该列表结果转换为所需的 numpy 数组,我们可以 "vectorize" 解决问题使用 numpy 的魔力。这在这里很方便,因为 pygame.surfarray.array3d
已经 returns 一个 numpy 数组!
这是一个可能的解决方案,可以获取图像(从磁盘加载;我无法让您的代码工作,因为它依赖于一些 linux 目录,例如 /dev/video0
用于网络摄像头输入和espeak
命令,在Windows中不可用):
import numpy as np
import pygame
import sys
if __name__ == "__main__":
pygame.init()
screen = pygame.display.set_mode((800, 600))
img = pygame.image.load("test.jpg").convert_alpha()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
data = pygame.surfarray.array3d(img)
mask = data[..., 2] < 200 #mark all super-NOT-blue pixels as True (select the OPPOSITE!)
masked = data.copy() #make a copy of the original image data
masked[mask] = [0, 0, 0] #set any of the True pixels to black (rgb: 0, 0, 0)
out = pygame.surfarray.make_surface(masked) #convert the numpy array back to a surface
screen.blit(out, (0, 0))
pygame.display.update()
print clock.get_fps()
clock.tick(60)
在我的电脑上,它的运行速度约为 30 fps,虽然不是很好,但应该是一个显着的改进!这里的缓慢似乎特别是由于 masked[mask] = [0, 0, 0]
。如果任何 numpy 专家可以插话,那就太棒了!否则,我可以用一个额外的 cython 答案代替(添加类型数据应该显着提高循环性能)。
我正在尝试迭代 pygame 3d surfarray,更具体地说 pygame.surfarray.array3d("your image")
。我正在接收从我的网络摄像头捕获的视频,然后将它们转换为 3d 数组,然后使用此代码将其显示到我的 window 上。
def cameraSee(self):
while True:
self.cam.query_image()
self.image = self.cam.get_image()
self.imageArr = pygame.surfarray.array3d(self.image)
pygame.surfarray.blit_array(self.screen,self.imageArr)
os.system("clear")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
我的问题是我试图让我的相机只显示蓝色量大于 200(范围从 0 - 255)的任何像素,并将所有其他像素的颜色值更改为 0。我'我已经尝试对数组使用 if 语句,但我收到一条错误消息,指出我应该使用 any()
或 all()
.
我所有的代码:
try:
import pygame
import pygame.camera
import pygame.surfarray
import numpy
import os
import sys
import time
except:
print("there was an error importing modules...")
os.system("espeak 'there, was, an, error, importing, modules'")
time.sleep(2)
class aaiVision(object):
def __init__(self,screen,cam,image,imageArr):
self.screen = screen
self.cam = cam
self.image = image
self.imageArr = imageArr
def startUp(self):
os.system("espeak 'eh, eh, i, vision, initializing'")
pygame.init()
pygame.camera.init()
time.sleep(1)
os.system("espeak 'Vision, initialized'")
camList = pygame.camera.list_cameras()
print(camList)
time.sleep(1)
os.system("espeak 'cameras, found, %s'" % str(len(camList)))
time.sleep(1)
self.screen = pygame.display.set_mode((640,480))
time.sleep(0.5)
self.cam = pygame.camera.Camera("/dev/video0",(640,480),"YUV")
time.sleep(0.5)
self.cam.start()
os.system("espeak 'eh, eh, i, vision, online'")
def cameraSee(self):
while True:
self.cam.query_image()
self.image = self.cam.get_image()
self.imageArr = pygame.surfarray.array3d(self.image)
pygame.surfarray.blit_array(self.screen,self.imageArr)
os.system("clear")
pygame.display.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
sys.exit()
eyesAwake = aaiVision('', '', '', '')
if __name__ == "__main__":
eyesAwake.startUp()
eyesAwake.cameraSee()
抱歉出现了一些缩进错误,我不确定如何使用文本代码块 XD
我不确定是否有效,但请尝试一下
outArr = np.array( [[w if w[2] > 200 else np.zeros(3) for w in h] for h in self.imageArr], dtype='uint8')
想法是三维数组具有三个索引,第一个描述位置的高度,第二个描述位置的宽度,最后一个描述像素的颜色。因此,如果颜色列表的第三个条目(对应于蓝色)大于 200,则比较颜色列表的列表理解。如果不是这种情况,则重置所有颜色值。
与其遍历列表理解中的像素(这在 python 中肯定会很慢),然后将该列表结果转换为所需的 numpy 数组,我们可以 "vectorize" 解决问题使用 numpy 的魔力。这在这里很方便,因为 pygame.surfarray.array3d
已经 returns 一个 numpy 数组!
这是一个可能的解决方案,可以获取图像(从磁盘加载;我无法让您的代码工作,因为它依赖于一些 linux 目录,例如 /dev/video0
用于网络摄像头输入和espeak
命令,在Windows中不可用):
import numpy as np
import pygame
import sys
if __name__ == "__main__":
pygame.init()
screen = pygame.display.set_mode((800, 600))
img = pygame.image.load("test.jpg").convert_alpha()
clock = pygame.time.Clock()
while True:
for event in pygame.event.get():
if event.type == pygame.QUIT:
pygame.quit()
sys.exit()
data = pygame.surfarray.array3d(img)
mask = data[..., 2] < 200 #mark all super-NOT-blue pixels as True (select the OPPOSITE!)
masked = data.copy() #make a copy of the original image data
masked[mask] = [0, 0, 0] #set any of the True pixels to black (rgb: 0, 0, 0)
out = pygame.surfarray.make_surface(masked) #convert the numpy array back to a surface
screen.blit(out, (0, 0))
pygame.display.update()
print clock.get_fps()
clock.tick(60)
在我的电脑上,它的运行速度约为 30 fps,虽然不是很好,但应该是一个显着的改进!这里的缓慢似乎特别是由于 masked[mask] = [0, 0, 0]
。如果任何 numpy 专家可以插话,那就太棒了!否则,我可以用一个额外的 cython 答案代替(添加类型数据应该显着提高循环性能)。