|  |  | @ -10,6 +10,7 @@ PIL_CONVERT_COLOR = { | 
			
		
	
		
		
			
				
					
					|  |  |  |     'full_YCbCr': lambda pil_image: pil_image.convert("YCbCr") if pil_image.mode != 'YCbCr'  else pil_image, |  |  |  |     'full_YCbCr': lambda pil_image: pil_image.convert("YCbCr") if pil_image.mode != 'YCbCr'  else pil_image, | 
			
		
	
		
		
			
				
					
					|  |  |  |     'full_Y': lambda pil_image: pil_image.convert("YCbCr").getchannel(0) if pil_image.mode != 'YCbCr'  else pil_image.getchannel(0), |  |  |  |     'full_Y': lambda pil_image: pil_image.convert("YCbCr").getchannel(0) if pil_image.mode != 'YCbCr'  else pil_image.getchannel(0), | 
			
		
	
		
		
			
				
					
					|  |  |  |     'sdtv_Y': lambda pil_image: _rgb2ycbcr(np.array(pil_image))[:,:,0] if pil_image.mode == 'RGB' else NotImplementedError(f"{pil_image.mode} to Y"), |  |  |  |     'sdtv_Y': lambda pil_image: _rgb2ycbcr(np.array(pil_image))[:,:,0] if pil_image.mode == 'RGB' else NotImplementedError(f"{pil_image.mode} to Y"), | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     'sdtv2_Y': lambda pil_image: rgb2y(np.array(pil_image)) if pil_image.mode == 'RGB' else NotImplementedError(f"{pil_image.mode} to Y"), | 
			
		
	
		
		
			
				
					
					|  |  |  |     'L': lambda pil_image: pil_image.convert("L") if pil_image.mode != 'L'  else pil_image, |  |  |  |     'L': lambda pil_image: pil_image.convert("L") if pil_image.mode != 'L'  else pil_image, | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
	
		
		
			
				
					|  |  | @ -32,3 +33,87 @@ def _rgb2ycbcr(img, maxVal=255): | 
			
		
	
		
		
			
				
					
					|  |  |  |     ycbcr = np.reshape(t, [img.shape[0], img.shape[1], img.shape[2]]) |  |  |  |     ycbcr = np.reshape(t, [img.shape[0], img.shape[1], img.shape[2]]) | 
			
		
	
		
		
			
				
					
					|  |  |  | 
 |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |     return ycbcr |  |  |  |     return ycbcr | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | def rgb2y(im): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     this impl: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.301,  0.586,  0.113  = 77/256, 150/256, 29/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.172, -0.340,  0.512  = -44/256, -87/256, 131/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.512, -0.430, -0.082  = 131/256, -110/256, -21/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[1]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.299,  0.587,  0.114 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.172, -0.339,  0.511 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.511, -0.428, -0.083 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[2]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.299,  0.587,  0.114 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.169, -0.331,  0.5 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.5,   -0.419, -0.081 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [1] Video Demystified A Handbook for the Digital Engineer 4th ed - keith Jack, Chapter 3 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [2] Color Space Conversions Adrian Ford, Alan Roberts | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     im = im.astype(np.float32) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     R, G, B = im[:,:,0], im[:,:,1], im[:,:,2] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Y =  77/256*R + 150/256*G +  29/256*B | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # [1] Note that 8-bit YCbCr and R'G'B' data should be saturated a | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return Y.clip(0,255).astype(np.uint8) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | def rgb2yuv(im): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     this impl: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.301,  0.586,  0.113  = 77/256, 150/256, 29/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.172, -0.340,  0.512  = -44/256, -87/256, 131/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.512, -0.430, -0.082  = 131/256, -110/256, -21/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[1]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.299,  0.587,  0.114 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.172, -0.339,  0.511 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.511, -0.428, -0.083 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[2]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.299,  0.587,  0.114 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     -0.169, -0.331,  0.5 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      0.5,   -0.419, -0.081 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [1] Video Demystified A Handbook for the Digital Engineer 4th ed - keith Jack, Chapter 3 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [2] Color Space Conversions Adrian Ford, Alan Roberts | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     im = im.astype(np.float32) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     R, G, B = im[:,:,0], im[:,:,1], im[:,:,2] | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Y =  77/256*R + 150/256*G +  29/256*B | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     U = -44/256*R -  87/256*G + 131/256*B | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     V = 131/256*R - 110/256*G -  21/256*B | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Y, U, V = Y, U + 128, V + 128 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # [1] Note that 8-bit YCbCr and R'G'B' data should be saturated at the 0 and 255 levels to avoid underflow and overflow | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return np.stack([Y,U,V], axis=-1).clip(0,255).astype(np.uint8) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | 
 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  | def yuv2rgb(im): | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     this impl: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,  0,      1.406     = 1, 0, 360/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1, -0.344, -0.719     = 1, -88/256, -184/256 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,  1.777,  0         = 1, 455/256, 0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[1]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,      0,  1.371 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1, -0.336, -0.698 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,  1.732,  0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     ycbcr 601 sdtv spec[2]: | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,      0,  1.403 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1, -0.344, -0.714 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     1,  1.773,  0 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [1] Video Demystified A Handbook for the Digital Engineer 4th ed - keith Jack, Chapter 3 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     [2] Color Space Conversions Adrian Ford, Alan Roberts | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     """ | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     im = im.astype(np.float32) | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Y, Ud, Vd = im[:,:,0], im[:,:,1]-128, im[:,:,2]-128 | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     R = Y + 360/256*Vd | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     G = Y -  88/256*Ud - 184/256*Vd | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     B = Y + 455/256*Ud | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     # [1] Note that 8-bit YCbCr and R'G'B' data should be saturated at the 0 and 255 levels to avoid underflow and overflow | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     return np.stack([R, G, B], axis=-1).clip(0,255).astype(np.uint8) |