Как вручную размыть изображение в python?

В приведенном ниже коде я пытаюсь размыть изображение в python, заменяя каждый пиксель средним значением окружающих его пикселей, если исходный пиксель не находится на границе изображения. Однако всякий раз, когда я запускаю свой код, я просто получаю черное изображение. Может ли кто-нибудь сказать мне, что я делаю неправильно?

import numpy as np
import matplotlib.pyplot as plt
from scipy.misc import imread, imsave, imresize

imgOld = imread('house.png') # read image into a numpy array
imgNew = imgOld
(imgH, imgW, imgC) = imgOld.shape # imgC = 2 or 4 (RGB or RGBA)
plt.imshow(imgOld, origin='lower')

# blur
for y in range(imgH):
    for x in range(imgW):
        xLast = 0
        yLast = 0
        if x != 0 and y != 0:
            xLast = (x-1) % imgW
            yLast = (y-1) % imgH
        else:
            xLast = 0
            yLast = 0
        xNext = (x+1) % imgW
        yNext = (y+1) % imgH
        rgb = imgNew[y,x]
        r = (imgOld[yLast,xLast,2]
                    + imgOld[yLast,x,2]
                    + imgOld[yLast,xNext,2]
                    + imgOld[y,xLast,2]
                    + imgOld[y,x,2]
                    + imgOld[y,xNext,2]
                    + imgOld[yNext,xLast,2]
                    + imgOld[yNext,x,2]
                    + imgOld[yNext,xNext,2]) / 9
        g = (imgOld[yLast,xLast,1]
                    + imgOld[yLast,x,1]
                    + imgOld[yLast,xNext,1]
                    + imgOld[y,xLast,1]
                    + imgOld[y,x,1]
                    + imgOld[y,xNext,1]
                    + imgOld[yNext,xLast,1]
                    + imgOld[yNext,x,1]
                    + imgOld[yNext,xNext,1]) / 9
        b = (imgOld[yLast,xLast,0]
                    + imgOld[yLast,x,0]
                    + imgOld[yLast,xNext,0]
                    + imgOld[y,xLast,0]
                    + imgOld[y,x,0]
                    + imgOld[y,xNext,0]
                    + imgOld[yNext,xLast,0]
                    + imgOld[yNext,x,0]
                    + imgOld[yNext,xNext,0]) / 9
        imgNew[y,x] = [b,g,r]
plt.imshow(imgNew, origin='lower')

Редактировать: я обновил свой код до среднего на основе отдельного значения цвета каждого пикселя, однако в результате я все еще получаю черное изображение.

Я добавляю свою отлично работающую java-версию этого кода. Я не понимаю, где я ошибаюсь

Java-версия:

protected void proc_17() {
    info = "Blur";
    for (int y = 0; y < imgH; y++) {
        for (int x = 0; x < imgW; x++) {
            int xLast = 0;
            int yLast = 0;
            if (x != 0 && y != 0) {
                xLast = (x-1) % imgW;
                yLast = (y-1) % imgH;
            } else {
                xLast = 0;
                yLast = 0;
            }
            int xNext = (x+1) % imgW;
            int yNext = (y+1) % imgH;
            float r = (imgOld.getR(xLast, yLast) 
                    + imgOld.getR(x, yLast) 
                    + imgOld.getR(xNext, yLast) 
                    + imgOld.getR(xLast, y) 
                    + imgOld.getR(x, y) 
                    + imgOld.getR(xNext, y) 
                    + imgOld.getR(xLast, yNext) 
                    + imgOld.getR(x, yNext) 
                    + imgOld.getR(xNext, yNext)) / 9;
            float g = (imgOld.getG(xLast, yLast) 
                    + imgOld.getG(x, yLast) 
                    + imgOld.getG(xNext, yLast) 
                    + imgOld.getG(xLast, y) 
                    + imgOld.getG(x, y) 
                    + imgOld.getG(xNext, y) 
                    + imgOld.getG(xLast, yNext) 
                    + imgOld.getG(x, yNext)
                    + imgOld.getG(xNext, yNext)) / 9;
            float b = (imgOld.getB(xLast, yLast) 
                    + imgOld.getB(x, yLast) 
                    + imgOld.getB(xNext, yLast) 
                    + imgOld.getB(xLast, y) 
                    + imgOld.getB(x, y) 
                    + imgOld.getB(xNext, y) 
                    + imgOld.getB(xLast, yNext) 
                    + imgOld.getB(x, yNext) 
                    + imgOld.getB(xNext, yNext)) / 9;
            imgNew.setR(x, y, r);
            imgNew.setG(x, y, g);
            imgNew.setB(x, y, b);
        }
    }
}

person Teej    schedule 25.04.2017    source источник
comment
взгляните на opencv   -  person Azat Ibrakov    schedule 25.04.2017
comment
Это домашнее задание? Актуальный проект? Вы знаете, что такое свертка и ядра?   -  person spectras    schedule 25.04.2017
comment
вы перебираете все элементы. Numpy может легко сделать это векторизованным. Информация, которая вам нужна, не так уж отличается от информации, необходимой Конвею для игры в жизнь, но вместо подсчета вам нужно среднее значение окружающих мест. Вы можете адаптировать что-то вроде это к вашей ситуации.   -  person Maarten Fabré    schedule 25.04.2017
comment
@spectras Это своего рода домашнее задание. Я уже успешно выполнил эту задачу на Java, но у меня возникли проблемы с преобразованием ее в python. И я не знаю, что такое свертка и ядра.   -  person Teej    schedule 25.04.2017
comment
Свертка — это, по сути, универсальная версия операции, которую вы пытаетесь реализовать. Он генерирует сигнал из взвешенных смещений исходного сигнала. Ваше размытие - это свертка с использованием ядра 3x3, заполненного коэффициентом 1/9. Дело в том, что numpy предоставляет полностью ускоренные методы для выполнения свертки. Если бы это не было домашним заданием, это было бы гораздо лучшим решением для достижения того, чего вы хотите. Но если это домашняя работа, ты должен сделать ее сам, я полагаю, отсюда и вопрос.   -  person spectras    schedule 25.04.2017
comment
Как это связано с Сейджем?   -  person Michael Fulton    schedule 03.05.2017


Ответы (1)


Проблема с этим кодом в том, что он не суммирует значения переменных r, g и b. Это может быть из-за отступов, поэтому я поместил эти значения в виде списка, подсчитал сумму и разделил ее на 9. Следуйте приведенному ниже сценарию:

 imgOld = imread('house.png') # read image into a numpy array imgNew =
 imgOld (imgH, imgW, imgC) = imgOld.shape # imgC = 2 or 4 (RGB or RGBA)
 
 plt.imshow(imgOld, vmin=0, vmax=255) plt.show()
 
 # blur for y in range(imgH):
     for x in range(imgW):
         xLast = 0
         yLast = 0
         if x != 0 and y != 0:
             xLast = (x-1) % imgW
             yLast = (y-1) % imgH
         else:
             xLast = 0
             yLast = 0
         xNext = (x+1) % imgW
         yNext = (y+1) % imgH
         rgb = imgNew[y,x]
 
         aux_r = (imgOld[yLast,xLast,2],
                       imgOld[yLast,x,2],
                       imgOld[yLast,xNext,2],
                       imgOld[y,xLast,2],
                       imgOld[y,x,2],
                       imgOld[y,xNext,2],
                       imgOld[yNext,xLast,2],
                       imgOld[yNext,x,2],
                       imgOld[yNext,xNext,2])
         r = sum(aux_r)
         r = r/9
         aux_g = (imgOld[yLast,xLast,1],
                       imgOld[yLast,x,1],
                       imgOld[yLast,xNext,1],
                       imgOld[y,xLast,1],
                       imgOld[y,x,1],
                       imgOld[y,xNext,1],
                       imgOld[yNext,xLast,1],
                       imgOld[yNext,x,1],
                       imgOld[yNext,xNext,1])
         g = sum(aux_g)
         g = g/9
 
         aux_b = (imgOld[yLast,xLast,0],
                       imgOld[yLast,x,0],
                       imgOld[yLast,xNext,0],
                       imgOld[y,xLast,0],
                       imgOld[y,x,0],
                       imgOld[y,xNext,0],
                       imgOld[yNext,xLast,0],
                       imgOld[yNext,x,0],
                       imgOld[yNext,xNext,0])
         b = sum(aux_b)
         b = b/9
             
         imgNew[y,x] = [b,g,r] plt.imshow(imgNew, vmin=0, vmx=255) plt.show()
 
person Rafaela Barbosa    schedule 21.02.2021