@@ -107,16 +107,23 @@ def loop(self):
107107class MemMap (MemoryMap ):
108108 def open (self ):
109109 super ().open ()
110+ self .opencv = False
110111 format = self .format
111112 if pixel_format := FORMAT_MAP .get (format .pixel_format ):
112113 self .data = bytearray (format .size )
113114 self .qimage = QtGui .QImage (self .data , format .width , format .height , pixel_format )
115+ elif format in OPENCV_FORMATS :
116+ self .data = bytearray (format .width * format .height * 3 )
117+ self .qimage = QtGui .QImage (self .data , format .width , format .height , QtGui .QImage .Format .Format_RGB888 )
118+ self .opencv = True
114119 else :
115120 self .data = None
116121 self .qimage = None
117122
118123 def raw_read (self , into = None ):
119124 frame = super ().raw_read (self .data )
125+ if self .data and frame .pixel_format in OPENCV_FORMATS :
126+ frame_to_rgb24 (frame , self .data )
120127 frame .user_data = self .qimage
121128 return frame
122129
@@ -578,26 +585,59 @@ def to_qpixelformat(pixel_format: PixelFormat) -> QtGui.QPixelFormat | None:
578585
579586
580587FORMAT_MAP = {
581- PixelFormat .RGB24 : QtGui .QImage .Format .Format_RGB888 ,
582- PixelFormat .RGB32 : QtGui .QImage .Format .Format_RGB32 ,
583- PixelFormat .RGBA32 : QtGui .QImage .Format .Format_RGBA8888 ,
584- PixelFormat .ARGB32 : QtGui .QImage .Format .Format_ARGB32 ,
585- PixelFormat .XRGB32 : QtGui .QImage .Format .Format_ARGB32 ,
586- PixelFormat .GREY : QtGui .QImage .Format .Format_Grayscale8 ,
588+ PixelFormat .RGB24 : QtGui .QImage .Format .Format_RGB888 , # ok
589+ PixelFormat .BGR24 : QtGui .QImage .Format .Format_BGR888 , # ok
590+ PixelFormat .RGB565 : QtGui .QImage .Format .Format_RGB16 , # ok
591+ PixelFormat .RGBX555 : QtGui .QImage .Format .Format_RGB555 , # ok ? Transparency
592+ PixelFormat .XRGB444 : QtGui .QImage .Format .Format_RGB444 , # ok
593+ PixelFormat .RGB32 : QtGui .QImage .Format .Format_ARGB32 , # wrong
594+ PixelFormat .RGBA32 : QtGui .QImage .Format .Format_RGBA8888 , # wrong no image!
595+ PixelFormat .ARGB32 : QtGui .QImage .Format .Format_ARGB32 , # wrong
596+ PixelFormat .XRGB32 : QtGui .QImage .Format .Format_RGB32 , # wrong (same problem as RGB32)
597+ PixelFormat .GREY : QtGui .QImage .Format .Format_Grayscale8 , # ok
598+ PixelFormat .Y16 : QtGui .QImage .Format .Format_Grayscale16 , # ok
599+ PixelFormat .RGBX32 : QtGui .QImage .Format .Format_RGBX8888 , # ok
600+ PixelFormat .RGBX1010102 : QtGui .QImage .Format .Format_RGB30 ,
601+ }
602+
603+ OPENCV_FORMATS = {
604+ PixelFormat .YUYV ,
605+ PixelFormat .YVYU ,
606+ PixelFormat .UYVY ,
607+ PixelFormat .YUV420 ,
608+ PixelFormat .NV12 ,
609+ PixelFormat .NV21 ,
587610}
588611
589612
613+ def frame_to_rgb24 (frame , into = None ):
614+ import cv2
615+
616+ YUV_MAP = {
617+ PixelFormat .YUYV : cv2 .COLOR_YUV2RGB_YUYV ,
618+ PixelFormat .YVYU : cv2 .COLOR_YUV2RGB_YVYU ,
619+ PixelFormat .UYVY : cv2 .COLOR_YUV2RGB_UYVY ,
620+ PixelFormat .YUV420 : cv2 .COLOR_YUV2RGB_I420 ,
621+ PixelFormat .NV12 : cv2 .COLOR_YUV2RGB_NV12 ,
622+ PixelFormat .NV21 : cv2 .COLOR_YUV2RGB_NV21 ,
623+ }
624+ data = frame .array
625+ fmt = frame .pixel_format
626+ if fmt in {PixelFormat .NV12 , PixelFormat .YUV420 }:
627+ data .shape = frame .height * 3 // 2 , frame .width , - 1
628+ else :
629+ data .shape = frame .height , frame .width , - 1
630+ return cv2 .cvtColor (data , YUV_MAP [fmt ], dst = into )
631+
632+
590633def frame_to_qimage (frame : Frame ) -> QtGui .QImage | None :
591634 """Translates a Frame to a QImage"""
592635 data = frame .data
593636 if frame .pixel_format == PixelFormat .MJPEG :
594637 return QtGui .QImage .fromData (data , "JPG" )
595- elif frame .pixel_format == PixelFormat .YUYV :
596- import cv2
597638
598- data = frame .array
599- data .shape = frame .height , frame .width , - 1
600- data = cv2 .cvtColor (data , cv2 .COLOR_YUV2BGR_YUYV )
639+ if frame .pixel_format in OPENCV_FORMATS :
640+ data = frame_to_rgb24 (frame )
601641 fmt = QtGui .QImage .Format .Format_RGB888
602642 else :
603643 if (fmt := FORMAT_MAP .get (frame .pixel_format )) is None :
@@ -857,6 +897,7 @@ def stop():
857897 window = QtWidgets .QWidget ()
858898 layout = QtWidgets .QHBoxLayout (window )
859899 video = QVideoWidget (camera )
900+ video .setMinimumSize (640 , 480 )
860901 panel = QControlPanel (camera )
861902 settings = QSettingsPanel (camera )
862903 layout .addWidget (settings )
0 commit comments