Изображение в оттенках серого python Реализация - PullRequest
3 голосов
/ 09 марта 2020

Я пытаюсь преобразовать RGB-изображение в оттенки серого, используя python как функцию, но проблема в том, что я даю ему RGB-изображение, которое имеет высоту, ширину и канал, но после кода у меня должно быть изображение только с высотой и шириной но это дает мне изображение с высотой, шириной и каналом, почему?

def RGBtoGRAY(img):
    height, width, channels = img.shape
    grayimg = img
    for i in range(height):
        for j in range(width):
            grayimg[i,j] = 0.3 * image[i,j][0] + 0.59 * image[i,j][1] +  0.11 * image[i,j][2]
    return grayimg

размер входного изображения

image.shape 
(533, 541, 3)

размер выходного изображения

grayimage.shape 
(533, 541, 3)

обычно я хочу найти по размеру выходного изображения

(533, 541)

Ответы [ 2 ]

1 голос
/ 09 марта 2020

Следует избегать использования циклов for при выполнении обработки изображений, поскольку она очень медленная. Вместо этого вы можете использовать Numpy, который высоко оптимизирован для векторных операций. Используя эту формулу преобразования шкалы яркости :

gray = R * .299 + G * .587 + B * .114

Метод № 1: apply_along_axis:

import cv2
import numpy as np

def grayscale(colors):
    r, g, b = colors
    return 0.299 * r + 0.587 * g + 0.114 * b

# Create image of size 100x100 of random pixels
# Convert to grayscale
image = np.random.randint(255, size=(100,100,3),dtype=np.uint8)
gray = np.apply_along_axis(grayscale, 2, image)

# Display
cv2.imshow('image', image)
cv2.imshow('gray', gray)
cv2.waitKey()

До -> После

enter image description here enter image description here

Метод № 2: cv2.cvtColor

Вы можете использовать OpenCV напрямую и считывать изображение в градациях серого с помощью cv2.imread, передавая флаг cv2.IMREAD_GRAYSCALE или 0, чтобы загрузить изображение в градациях серого. .

image = cv2.imread('img.png', cv2.IMREAD_GRAYSCALE) # OR
# image = cv2.imread('img.png', 0)

Если изображение уже загружено, вы можете преобразовать изображение RGB или BGR в оттенки серого, используя cv2.cvtColor

image = cv2.imread('img.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
0 голосов
/ 10 марта 2020

Предполагая, что вы используете для l oop, потому что вы намерены решить его "вручную" (например, код C), у вашей реализации есть ряд проблем:

  • присвоение grayimg = img в Python не создает копию img (в результате grayimg ссылается на img).
    Вы предполагали использовать: grayimg = img.copy().
  • img имеет 3 измерений, поэтому при использовании grayimg = img, grayimg также имеет 3 измерения.
    Вам необходимо создать grayimg с двумя измерениями.
    Пример для создания grayimg и инициализируйте нулями:

    grayimg = np.zeros((height, width), img.dtype)
    
  • Внутри для l oop вместо img используется image.

Вот исправленная версия RGBtoGRAY:

def RGBtoGRAY(img):
    height, width, channels = img.shape
    #grayimg = img
    # Create height x width array with same type of img, and initialize with zeros.
    grayimg = np.zeros((height, width), img.dtype)
    for i in range(height):
        for j in range(width):
            grayimg[i,j] = 0.3 * img[i,j][0] + 0.59 * img[i,j][1] +  0.11 * img[i,j][2]
    return grayimg
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...