Python: แปลงภาพจาก RGB เป็นพื้นที่สี YDbDr

Nov 18 2020

พยายามแปลงภาพจากพื้นที่สี RGB เป็นพื้นที่สี YDbDr ตามสูตร:

Y = 0.299R + 0.587G + 0.114B

Db = -0.45R - 0.883G +1.333B

Dr = -1.333R + 1.116G + 0.217B

ด้วยรหัสต่อไปนี้ฉันพยายามแสดงเฉพาะช่อง Y ซึ่งควรเป็นภาพโทนสีเทา แต่ฉันยังคงได้ภาพเป็นสีฟ้า:

import numpy as np
from PIL import Image
import cv2
import matplotlib.pyplot as plt

img = cv2.imread("./pics/Slike_modela/Test/Proba/1_Color.png")
new_img = []
for row in img:
    new_row = []
    for pixel in row:
        Y = 0.299*pixel[2]+0.587*pixel[1]+0.114*pixel[0]
        Db = -0.45*pixel[2]-0.883*pixel[1]+1.333*pixel[0]
        Dr = -1.333*pixel[2]+1.116*pixel[1]+0.217*pixel[0]
        new_pixel = [Y, Db, Dr]
        new_row.append(new_pixel)
    new_img.append(new_row)

new_img_arr = np.array(new_img)
new_img_arr_y = new_img_arr.copy()
new_img_arr_y[:,:,1] = 0
new_img_arr_y[:,:,2] = 0
print (new_img_arr_y)
cv2.imshow("y image", new_img_arr_y) 
key = cv2.waitKey(0)

เมื่อพิมพ์อาร์เรย์ผลลัพธ์ฉันเห็นตัวเลขที่ถูกต้องตามสูตรและรูปร่างที่ถูกต้องของอาร์เรย์

ความผิดพลาดของฉันคืออะไร? วิธีการรับภาพช่อง Y เช่นภาพสีเทา?

คำตอบ

1 MarkSetchell Nov 22 2020 at 13:19

เมื่อประมวลผลภาพด้วย Python คุณควรพยายามหลีกเลี่ยง:

  • ปฏิบัติต่อรูปภาพเป็นรายการและต่อท้ายพิกเซลนับล้านล้านพิกเซลซึ่งแต่ละภาพจะสร้างวัตถุใหม่ทั้งหมดและใช้พื้นที่ในการจัดการ

  • การประมวลผลภาพด้วยการforวนซ้ำซึ่งช้ามาก

วิธีที่ดีกว่าในการจัดการกับทั้งสองอย่างนี้คือการใช้Numpyหรือไลบรารีโค้ดหรือเทคนิค vectorised อื่น ๆ นั่นคือเหตุผลที่OpenCV , wand, scikit-imageเปิดและจับภาพอาร์เรย์ Numpy

ดังนั้นโดยพื้นฐานแล้วคุณต้องการทำผลิตภัณฑ์ดอทของช่องสีด้วยชุด 3 น้ำหนัก:

import cv2
import numpy as np

# Load image
im = cv2.imread('paddington.png', cv2.IMREAD_COLOR)

# Calculate Y using Numpy "dot()"
Y = np.dot(im[...,:3], [0.114, 0.587, 0.299]).astype(np.uint8)

แค่นั้นแหละ.