2013-07-12 4 views
7

Я пытаюсь написать алгоритм конвертеров, который принимает изображение в формате JPEG и возвращает его версию PGM (Portable Grey Map). Проблема в том, что я не могу понять, как работают «официальные» конвертеры JPG-> PGM с точки зрения того, какое значение следует назначать последнему пикселю (я думаю, 0-> 255), начиная с классического формата RGB.«Стандартное» преобразование RGB в оттенки серого

В начале, я использовал эту формулу (это то же самое используется преобразование CV_RGB2GRAY OpenCV в):

0,30 * R + 0.59 * G + 0,11 * В = Val

Я написал простой код проверить мои результаты: требуется цветное изображение и его версия PGM (уже преобразованная с использованием GIMP). Затем он преобразует цветное изображение с использованием предыдущей формулы. Цель состоит в том, чтобы иметь изображение в градациях серого, которое является пикселем в пиксель, равным входному сигналу PGM.

На данный момент он не возвращает те же значения. Вы можете мне помочь?

+0

Вы уже видели [википедия: Оттенки серого] (https://en.wikipedia.org/wiki/Grayscale)? – MrSmith42

+0

Вы уверены, что это то, что он делает? Что, если он просто декодирует плоскость Y и игнорирует цветовые коэффициенты? У вас будет другой шум, и факторы могут быть разными. – harold

+0

Извините, я не понимаю вашего сообщения – TheUnexpected

ответ

5

Проблема заключается в том, что я не могу понять, как работают «официальные» преобразователи JPG-> PGM с точки зрения того, какое значение следует назначать последнему пикселю (я думаю, 0-> 255), начиная с классического RGB.

Вероятно, в преобразовании используется гамма-коррекция, используемая этими «официальными» инструментами.
То есть, это не просто линейное преобразование.

Смотрите этот раздел Википедии для деталей: Converting color to grayscale

Я полагаю, вы хотите использовать формулу для Csrgb.
Попробуйте и посмотрите, совпадает ли он с результатами, которые вы ожидаете.

В принципе, вы будете делать это:

  1. Возьмите R, G, B цвет (каждый в [0,1] диапазоне)
    • Если они находятся в диапазоне 0..255 вместо этого, просто разделить на 255.0
  2. Расчет Clinear = 0.2126 R + 0.7152 G + 0.0722 B
    • Это, скорее всего, линейный преобразования вы применяли до того
  3. Compute Csrgb в соответствии с его формула, основанная на Clinear
    • Это нелинейная гамма-коррекция части вы отсутствовали
    • ЗАКАНЧИВАТЬ this WolframAlpha plot
    • Csrgb = 12.92 Clinear когда Clinear <= 0.0031308
    • Csrgb = 1.055 Clinear1/2.4 - 0.055, когда Clinear > 0.0031308
+0

@ alessandro.francesconi Я немного обновил ответ, чтобы изложить точные шаги, поскольку страница Википедии может быть немного загадочной, если вы не знакомы с некоторыми из основных наук о цветах. –

+1

@ alessandro.francesconi Я также добавил для вас график WolframAlpha, чтобы вы могли видеть нелинейную форму гамма-коррекции. –

+0

Тимоти, пожалуйста, поправьте меня, если я ошибаюсь, но я думаю, что после шага (1) вы должны преобразовать значения в линейную интенсивность, так как, когда вы берете значения RGB из файла, они уже гамма-кодируются с мощностью 1/2.4. Поэтому сначала вам нужно удалить эту кодировку, применив преобразование с мощностью 2.4, и только затем выполните шаги (2) и (3) вашего ответа. Это правильно? –

1

В теории, с несколькими пикселями (в данном случае, 3), вы можете определить, что делает их алгоритм. Juste ковырять три пикселя (p1, p2, p3), их значение RGB и их PGM значение серого, и у вас есть:

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 = р3 .grayValue.

Затем разрешите эту проблему (найдите «решатель уравнения» или что-то еще) и посмотрите, какие константы они используют.

+0

Спасибо, но нет, это не работает. Я поставил 3 пиксельных значения и решил систему уравнений с тремя уравнениями. Это приводит к трем константам, которые хороши для этих уравнений, а не для четвертого пикселя. – TheUnexpected

+0

1) Вы уверены, что выбрали одинаковые пиксели для значения RGB и серого? 2) из ​​этой статьи: http: //www.tannerhelland.com/3643/grayscale-image-algorithm-vb6/Я видел, что они были несколькими различными алгоритмами RGB-to-PGM. Попробуйте их все и попытайтесь выяснить, какой из них используется. Удачи! – Fabinout

+0

Что, если я скажу вам, что не нашел подходящего метода? – TheUnexpected

1

SIMPLE АЛГОРИТМ ПЕРЕВЕСТИ изображения RGB в полутоновое В OpenCV PYTHON!

Я использовал комментарии, поэтому код не требует пояснений. Но он работает быстро.

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 Я использовал этот файл изображения ... enter image description here

Моя программа генерируется следующий Grayscale файл ..

enter image description here

0

К точке Гарольда о "Y плоскости": стандартный цвет JPEG кодируются с использованием цветового пространства YCbCr, где Y - компонент яркости (т.е. яркость), а Cb и Cr - компоненты цветности с синей разницей и красной разностью. Таким образом, один из способов превратить цветной JPEG в оттенки серого - это просто отказаться от компонентов Cb и Cr.

Существует утилита под названием jpegtran, чем это можно сделать без потерь, используя опцию -grayscale. (Часть без потерь действительно имеет значение только в том случае, если вы хотите получить JPEG, а не PGM, чтобы избежать generation loss.) В любом случае это, вероятно, самый быстрый способ сделать это преобразование, поскольку он даже не декодирует изображение в пикселях, а тем более математическое на каждом.

Смежные вопросы