2013-07-12 46 views
7

Tôi đang cố viết một thuật toán chuyển đổi chụp ảnh JPEG và trả về phiên bản PGM (Bản đồ màu xám di động) của nó. Vấn đề là tôi không thể hiểu cách các trình chuyển đổi JPG -> PGM "chính thức" hoạt động theo giá trị nào để gán cho pixel cuối cùng (tôi đoán là 0-> 255) bắt đầu từ định dạng RGB cổ điển."Chuẩn" RGB to Chuyển đổi thang độ xám

Lúc đầu, tôi đã sử dụng công thức này (nó giống được sử dụng bởi chuyển đổi CV_RGB2GRAY của OpenCV):

0.30 * R + 0,59 * G + 0.11 * B = val

Tôi đã viết một mã đơn giản để kiểm tra kết quả của tôi: nó có một hình ảnh màu và phiên bản PGM của nó (đã được chuyển đổi bằng cách sử dụng GIMP). Sau đó, nó chuyển đổi hình ảnh màu bằng cách sử dụng công thức trước đó. Mục tiêu là để có một hình ảnh màu xám là pixel-to-pixel bằng đầu vào PGM.

Tại thời điểm này, nó không trả về cùng giá trị. Bạn có thể giúp tôi được không?

+0

Bạn đã xem [wikipedia: Grayscale] (https://en.wikipedia.org/wiki/Grayscale) chưa? – MrSmith42

+0

Bạn có chắc đó là những gì nó làm? Điều gì sẽ xảy ra nếu nó chỉ giải mã mặt phẳng Y và bỏ qua các hệ số màu? Bạn sẽ có tiếng ồn khác nhau, và các yếu tố có thể khác nhau. – harold

+0

Xin lỗi, tôi không hiểu bài đăng của bạn – TheUnexpected

Trả lời

5

Vấn đề là tôi không thể hiểu cách chuyển đổi JPG -> PGM "chính thức" hoạt động theo giá trị nào để gán cho pixel cuối cùng (tôi đoán, 0-> 255) bắt đầu từ cổ điển Định dạng RGB.

Có khả năng điều chỉnh gamma trong chuyển đổi những công cụ "chính thức" đang sử dụng.
Tức là, nó không chỉ là một biến đổi tuyến tính.

Xem phần này Wikipedia cho các chi tiết: Converting color to grayscale

Tôi tin rằng bạn muốn sử dụng công thức cho Csrgb.
Hãy dùng thử và xem nó có phù hợp với kết quả bạn mong đợi hay không.

Về cơ bản, bạn sẽ làm điều này:

  1. Hãy R, G, B màu (mỗi trong [0,1] range)
    • Nếu họ đang ở trong phạm vi 0..255 thay vào đó, chỉ đơn giản là chia 255.0
  2. Tính toán Clinear = 0.2126 R + 0.7152 G + 0.0722 B
    • Đây có thể là tuyến tính chuyển đổi bạn đã áp dụng trước
  3. Tính Csrgb theo đó là công thức, dựa trên Clinear
    • Đây là mảnh phi tuyến chỉnh gamma bạn bị mất tích
    • Check-out this WolframAlpha plot
    • Csrgb = 12.92 Clinear khi Clinear <= 0.0031308
    • Csrgb = 1.055 Clinear1/2.4 - 0.055 khi Clinear > 0.0031308
+0

@ alessandro.francesconi Tôi cập nhật câu trả lời một chút để đánh vần các bước chính xác, vì trang Wikipedia có thể hơi khó hiểu nếu bạn không quen với một số khoa học màu cơ bản. –

+1

@ alessandro.francesconi Tôi cũng đã thêm một âm mưu WolframAlpha cho bạn để bạn có thể thấy hình dạng phi tuyến của hiệu chỉnh gamma. –

+0

Timothy, hãy sửa tôi nếu tôi sai, nhưng tôi nghĩ sau bước (1) bạn phải chuyển đổi giá trị sang cường độ tuyến tính, vì khi bạn lấy giá trị RGB từ tệp, chúng đã được mã hóa bằng gamma với công suất 1/2.4. Vì vậy, trước tiên bạn cần phải loại bỏ mã hóa này bằng cách áp dụng biến đổi với power 2.4, và chỉ sau đó làm các bước (2) và (3) của câu trả lời của bạn. Có đúng không? –

1

Về lý thuyết, với một vài pixel (3, trong trường hợp này), bạn có thể xác định thuật toán của họ đang làm gì. Juste chọn của bạn ba pixel (p1, p2, p3), giá trị RGB của họ và giá trị xám PGM của họ, và bạn có:

RedConstant * p1.redValue + GreenConstant * p1.greenValue + BlueConstant * p1.blueValue = p1 .grayValue

RedConstant * p2.redValue + GreenConstant * p2.greenValue + BlueConstant * p2.blueValue = p2.grayValue

RedConstant * p3.redValue + GreenConstant * p3.greenValue + BlueConstant * p3.blueValue = p3 .grayValue.

Sau đó, giải quyết vấn đề này (tra cứu "phương trình giải quyết" hoặc một cái gì đó) và xem các hằng số mà chúng sử dụng là gì.

+0

Cảm ơn nhưng, không, nó không hoạt động. Tôi đặt 3 giá trị pixel và giải được một hệ ba phương trình. Nó kết quả trong ba hằng số tốt cho các phương trình đó chứ không phải cho một điểm ảnh thứ tư. – TheUnexpected

+0

1) Bạn có chắc chắn đã chọn cùng một pixel cho giá trị RGB và xám không? 2) từ bài viết này: http: //www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/Tôi thấy rằng chúng là một số thuật toán RGB-to-PGM khác nhau. Hãy thử tất cả và cố gắng khám phá cái nào được sử dụng. Chúc may mắn! – Fabinout

+0

Nếu tôi nói với bạn rằng tôi không tìm thấy phương pháp hợp lệ nào thì sao? – TheUnexpected

1

SIMPLE thuật toán để CONVERT RGB IMAGE sang gam màu xám trong OpenCV PYTHON!

Tôi đã sử dụng nhận xét để mã tự giải thích. Nhưng nó hoạt động nhanh chóng.

import cv2 
import numpy as np 
img1 = cv2.imread('opencvlogo.png') 
row,col,ch = img1.shape 
g = [ ] #the list in which we will stuff single grayscale pixel value inplace of 3 RBG values 
#this function converts each RGB pixel value into single Grayscale pixel value and appends that value to list 'g' 
def rgb2gray(Img): 
    global g 
    row,col,CHANNEL = Img.shape 
    for i in range(row) : 
     for j in range(col): 
     a =  ( Img[i,j,0]*0.07 + Img[i,j,1]*0.72 + Img[i,j,2] *0.21 ) #the algorithm i used id , G = B*0.07 + G*0.72 + R* 0.21 
                        #I found it online 
     g.append(a) 
rgb2gray(img1) #convert the img1 into grayscale 
gr = np.array(g) #convert the list 'g' containing grayscale pixel values into numpy array 
cv2.imwrite("test1.png" , gr.reshape(row,col)) #save the image file as test1.jpg 

SO Tôi đã từng tập tin ảnh này ... enter image description here

chương trình của tôi được tạo ra sau tập Grayscale ..

enter image description here

0

Đến thời điểm harold về các "máy bay Y": chuẩn màu Các ảnh JPEG được mã hóa bằng cách sử dụng không gian màu YCbCr, trong đó Y là thành phần độ sáng (tức là độ sáng) và Cb và Cr là các thành phần màu xanh khác biệt và màu đỏ khác biệt. Vì vậy, một cách để biến một màu JPEG thành một màu xám là chỉ cần thả các thành phần Cb và Cr.

Có một tiện ích gọi là jpegtran hơn là có thể thực hiện việc này một cách mất mát, sử dụng tùy chọn -grayscale. (Phần mất mát sẽ thực sự quan trọng nếu bạn muốn kết thúc với JPEG và không phải PGM, để tránh generation loss.) Trong mọi trường hợp, đây có thể là cách nhanh nhất để thực hiện phép chuyển đổi này, vì nó thậm chí không giải mã được hình ảnh thành pixel, ít nhiều làm toán trên mỗi một.