24-битная цветная схема и 8-битная диаграмма серого
Во-первых, давайте представим 24-битное цветное изображение. В 24-битном цветном изображении каждый пиксель представлен тремя байтами, обычно выражаемыми как RGB. Как правило, многие 24-разрядные цветные изображения хранятся как 32-разрядные изображения, а избыточные байты на пиксель хранятся в виде alpha значения, показывая информацию о специальном влиянии [1].
В модели RGB, если r = g = b, цвет представляет цвет серого, где значение r = g = b называется значением серого. Следовательно, каждый пиксель изображения серого, требуется только один байт для хранения значения серого, также известного как значение интенсивности и значение яркости), а диапазон серого составляет 0-255 [2]. Это дает вам изображение картины.
Несколько методов серого
1. Метод компонента: используйте один из трех компонентов RGB в качестве значения серого серого карты серого.
2. Большинство значений метод: используйте максимальное или минимальное значение трех компонентов RGB в качестве значения серого серого карты серого.
3.
4. Способ взвешивания: из-за различной цветовой чувствительности человеческих глаз средневзвешенные трехкомпоненты RGB могут получить более разумное изображение серого. Общая ситуация заключается в следующем: Y = 0,30R + 0,59G + 0,11b.
[Примечание] Метод взвешивания фактически принимает значение яркости изображения в качестве значения серого для расчета, и использует модель YUV. В [3] вы обнаружите, что автор использовал y = 0,21 * r + 0,71 * g + 0,07 * b для расчета значения серого (очевидно, сумма трех весов не равна 1, что может быть ошибкой автора?). Фактически, эта разница должна быть связана с тем, используется ли гамма -коррекция [1].
Метод реализации серого на Java
Если вы ищете «Java реализует серогойс», большинство из них являются одним из методов (код):
public void greyimage () throws ioException {file file = new File (System.getProperty ("user.dir")+"/test.jpg"); BufferedImage Image = imageio.read (файл); int width = image.getWidth (); int height = image.getheight (); BufferedImage greyimage = new BufferedImage (ширина, высота, bufferedimage.type_byte_gray); for (int i = 0; i <width; i ++) {for (int j = 0; j <height; j ++) {int rgb = image.getrgb (i, j); greyimage.setrgb (i, j, rgb); }} Файл newFile = new File (System.getProperty ("user.dir")+"/method1.jpg"); Imageio.write (greyimage, "jpg", newfile); }Исходное изображение test.jpg:
Диаграмма серого, полученная с использованием приведенного выше метода:
Видеть, как это изображение серого кажется возможным, но если мы используем opencv для достижения серого или использования PIL (Python), вы обнаружите, что эффекты сильно различаются:
img = cv2.imread ('test.jpg', cv2.imread_color) grey = cv2.cvtcolor (img, cv2.color_bgr2gray) cv2.imwrite ('pythonmethod.jpg', grey) Ясно видно, что график серого, полученный с использованием opencv (то же самое относится и к PIL), намного лучше, чем метод, полученный при вышеуказанном методе Java, и можно увидеть много деталей. Это показывает, что этот популярный метод в Интернете всегда была некоторая проблема, но его игнорировали.
Как достичь серого в OpenCV
Если у вас есть чтение книг или кодов, связанных с opencv , вы, вероятно, можете знать, что opencv GreyScale использует метод взвешивания. Причина в том, что это примерно потому, что мы не знаем, почему изображения серого opencv настолько хороши. Есть ли другие детали обработки, которые мы игнорируем?
Проверка наше предположение очень просто. Просто проверьте изменения до и после того, как значение пикселя будет сето. Вы можете проверить это следующим образом:
img = cv2.imread ('test.jpg', cv2.imread_color) H, W = img.shape [: 2] grey = cv2.cvtcolor (img, cv2.color_bgr2gray) для j в диапазоне (w): для i в диапазоне (h): print str (i) + ":" + str (j) + "(i) [i) [i) [i) [i) [i) [i). IMG [H-1] [W-1] [0: 3]Нам трудно судить о столько пикселях ниже, но нам нужно только обратить внимание на последнюю точку пикселя, и мы можем найти подсказки: значение RGB последней точки пикселя в исходном изображении составляет 44, 67, 89, а значение после серого - 71. Он просто соответствует расчетному значению серого масштаба. Если вы проверете значения пикселей изображения, которое раньше было выделено в Java, вы обнаружите, что не только значения пикселей не соответствуют этой формуле, но и даже далеко друг от друга.
На этом этапе мы предполагаем, что OpenCV (включая PIL) является реализацией серого с использованием метода взвешивания.
Java реализует взвешенный метод серогой
Если этот популярный метод в Интернете не работает, как мы должны использовать Java для достижения серого? Фактически, [3] успешно достиг (множество методов) серого (иностранные друзья по -прежнему очень мощные по технологиям), и здесь извлекается только необходимый код:
private static int colortorgb (int alpha, int red, int green, int blue) {int newpixel = 0; newpixel += alpha; newPixel = newPixel << 8; newpixel += красный; newPixel = newPixel << 8; newpixel += green; newPixel = newPixel << 8; newpixel += blue; вернуть Newpixel; } public static void main (string [] args) бросает ioException {buffereMage buffereMage = imageio.read (новый файл (System.getProperty ("user.dir" + "/test.jpg")); BufferedImage greyimage = new BuffereMage (BuffereMage.getWidth (), BuffereMage (); DuferImage ();) (int i = 0; i <bufferedimage.getwidth (); i ++) {for (int j = 0; j <bufferedimage.getheight (); J ++) {) (0,3 * R + 0,59 * G + 0,11 * B) ;; "/ok.jpg"); Приведенный выше код распечатает значения пикселей в масштабе серого цвета. Если вы сравните их с приведенным выше кодом Python, вы обнаружите, что значения Pixel полностью соответствуют. Метод colorToRGB обрабатывает цветовую диаграмму ровно 4 байта, одним из которых является alpha -параметр (как упоминалось ранее). Следующий рисунок - изображение серого этого кода:
Для других методов то же самое можно получить по очереди.
Суммировать
Причиной этой статьи является использование Java для реализации нескольких операций с серого и использования OpenCV для проверки правильного или неправильного конверсии. Тем не менее, некоторые проблемы были обнаружены в реальных тестах (существуют различия в преобразованных изображениях, и как генерировать изображения в серости на основе значений серого после преобразования), и некоторые мысли и проверки были сделаны на этом. Здесь следует отметить, что некоторые статьи в Интернете имеют более или менее сделанное дальнейшее мышление (и многие из них даже скопированы, особенно домашние статьи), и для этих практических проблем практическая реализация и проверка являются очень важным методом. Я надеюсь, что содержание этой статьи будет полезно для всех. Если у вас есть какие -либо вопросы, пожалуйста, оставьте сообщение для обсуждения.