Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Best way to display the texture produced in python on a spatial material #371

Open
TheBricktop opened this issue Sep 9, 2022 · 4 comments

Comments

@TheBricktop
Copy link

TheBricktop commented Sep 9, 2022

Im trying to do a simple camera feed on a quad but im missing something when it comes to handling the textures in the python script :

  from godot import exposed, export
  from godot import *
  import ctypes 
  import subprocess
  import sys
  import cv2
  import depthai as dai
  import numpy as np

  @exposed
   class Main(Spatial):
    # member variables here, example:
material = export (SpatialMaterial)
texture = None
def frame_to_godot_image(self, frame):
	image = Image()
	height, width, channels = frame.shape
	print(width, height)
	size = width * height * 3

	pool_array = PoolByteArray()
	pool_array.resize(size)

	with pool_array.raw_access() as ptr:
		numpy_array = np.ctypeslib.as_array(ctypes.cast(ptr.get_address(), ctypes.POINTER(ctypes.c_uint8)), (size,))
		numpy_array[:] = np.frombuffer(frame, dtype=np.uint8).reshape(height,width,channels).flatten()

	image.create_from_data(height, width, False, Image.FORMAT_RGB8, pool_array)
	return image
vid = cv2.VideoCapture(0)
image = None

def _ready(self):
	print("YEllo")
	#if self.material is not None:
	#	self.material.albedo_texture = self.texture

def _process(self,delta):
	ret, frame = self.vid.read()
	image = self.frame_to_godot_image(frame)
	#self.texture = image
	self.material.albedo_texture = image

`
im getting no errors but the image is not showing on the quad in fron of the camera.

@TheBricktop
Copy link
Author

TheBricktop commented Sep 10, 2022

okay after some tinkering ive got some results
current code

from godot import exposed, export
from godot import *
import ctypes 
import subprocess
import sys
import cv2
import depthai as dai
import numpy as np

@exposed
class Main(Spatial):
# member variables here, example:
material = export (SpatialMaterial)
texture = ImageTexture()
def frame_to_godot_image(self, frame):
	height, width, channels = frame.shape
	
	print(width, height, channels)
	image = Image()
	size = width * height * channels

	pool_array = PoolByteArray()
	pool_array.resize(size)

	with pool_array.raw_access() as ptr:
		numpy_array = np.ctypeslib.as_array(ctypes.cast(ptr.get_address(), ctypes.POINTER(ctypes.c_uint8)), (size,))
		numpy_array[:] = np.frombuffer(frame, dtype=np.uint8).reshape(channels,height,width).flatten()

	image.create_from_data(height, width, False, Image.FORMAT_RGB8, pool_array)
	return image
vid = cv2.VideoCapture(0)


def _ready(self):
	print("YEllo")
	#if self.material is not None:
	#	self.material.albedo_texture = self.texture

def _process(self,delta):
	ret, bgr = self.vid.read()
	frame = cv2.cvtColor(bgr, cv2.COLOR_YUV2RGB)
	image = self.frame_to_godot_image(frame)
	self.texture.create_from_image(image) 
	self.material.albedo_texture = self.texture

but now im getting interlaced image with shift to green

obraz

ive tried bgr to rgb and various formats but none is changing for the better

@Zireael07
Copy link

check material and mesh settings: is HDR on? is mirror/repeat on?

@Zireael07
Copy link

Also IIRC opencv uses some weird format/color ordering, IIRC it's not RGB but YCK or something (yes, not even the standard CMYK)

@TheBricktop
Copy link
Author

well that helped :

from godot import exposed, export
from godot import *
import ctypes 
import subprocess
import sys
import cv2
import numpy as np

  @exposed
  class Main(Spatial):
  # member variables here, example:
material = export (SpatialMaterial)
texture = ImageTexture()

vid = cv2.VideoCapture(0)
pool_array = PoolByteArray()

frame, height, width, channels, size = None,None,None,None,None

def frame_to_godot_image(self, frame, height, width, channels, size):
	print(width, height, channels)
	image = Image()
	

	with self.pool_array.raw_access() as ptr:
		numpy_array = np.ctypeslib.as_array(ctypes.cast(ptr.get_address(), ctypes.POINTER(ctypes.c_uint8)), (size,))
		numpy_array[:] = np.frombuffer(frame, dtype=np.uint8).reshape((height,width)[::-1]+(channels,)).flatten()

	image.create_from_data( width, height, False, Image.FORMAT_RGB8, self.pool_array)
	return image

def _ready(self):
	print("YEllo")
	ret, frame = self.vid.read()
	self.height, self.width, self.channels = frame.shape
	self.size = self.width * self.height * self.channels
	self.pool_array.resize(self.size)
	#if self.material is not None:
	#	self.material.albedo_texture = self.texture

def _process(self,delta):
	ret, frame = self.vid.read()
	image = self.frame_to_godot_image(frame,self.height, self.width, self.channels, self.size)
	self.texture.create_from_image(image) 
	self.material.emission_texture = self.texture

ive simply switched the height and width variables around

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants