Разное с изображением сворачивается с конвой из керас - PullRequest
1 голос
/ 01 июля 2019

Цель состоит в том, чтобы использовать настройку веса на первом слое модели, чтобы полностью заполнить функцию фильтра верхних частот - сделать первый слой модели таким же, как фильтр верхних частот для изображения.

1. Во-первых, подобное решение будет таким: использование фильтра верхних частот при обработке изображения, создание нового изображения и использование его в модели.--- для этого нужно использовать обработку изображения, которая стоит времени.

2. Я хочу установить слой Conv2D, который также может передавать изображение с высокой скоростью.с пользовательским фильтром (в качестве инициализатора).Основным является то, что фильтр и conv2D используют правила свертки.

, но результаты отличаются от первого решения.

#The image processing code:
    kernel55 = np.array([[-1, 2, -2, 2, -1], 
                         [2, -6, 8, -6, 2], 
                         [-2, 8, -12, 8, -2], 
                         [2,-6, 8, -6, 2],
                         [-1, 2, -2, 2, -1]])/12
        # load the image, pre-process it, and store it in the data list
        image = cv2.imread('1.pgm',-1)
        image = ndimage.convolve(image, kernel55)
        print(image)

#the first layer of the Model:

    def kernel_init(shape):
        kernel = np.zeros(shape)
        kernel[:,:,0,0] = np.array([[-1, 2, -2, 2, -1], 
                             [2, -6, 8, -6, 2], 
                             [-2, 8, -12, 8, -2], 
                             [2,-6, 8, -6, 2],
                             [-1, 2, -2, 2, -1]])/12
        return kernel
    #Build Keras model
    model = Sequential()
    model.add(Conv2D(1, [5,5], kernel_initializer=kernel_init, 
                     input_shape=(256,256,1), padding="same",activation='relu'))
    model.build()

test_im=cv2.imread('1.pgm',-1)  # define a test image
test_im=np.expand_dims(np.expand_dims(np.array(test_im),2),0)
out = model.predict(test_im)

Проблема в том, что использование обработки изображений позволяет получить правильное изображение с высокой скоростью передачи, но использование Conv2D - не тот же результат.

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

Почему, и есть ли какие-либо проблемы с моими мыслями?

1 Ответ

1 голос
/ 01 июля 2019

Извините за неполный ответ, но у меня есть кое-что, что частично работает, и некоторое объяснение.Вот код:

import cv2
import numpy as np
import scipy.ndimage as ndimage
from keras.models import Sequential
from keras.layers import Dense, Activation, Conv2D

#The image processing code:
#the first layer of the Model:

def kernel_init(shape):
    kernel = np.zeros(shape)
    kernel[:,:,0,0] = np.array([[-1, 2, -2, 2, -1],
                         [2, -6, 8, -6, 2],
                         [-2, 8, -12, 8, -2],
                         [2,-6, 8, -6, 2],
                         [-1, 2, -2, 2, -1]])
    #kernel = kernel/12
    #print("Here is the kernel")
    #print(kernel)
    #print("That was the kernel")
    return kernel

def main():
    print("starting")
    kernel55 = np.array([[-1, 2, -2, 2, -1],
                         [2, -6, 8, -6, 2],
                         [-2, 8, -12, 8, -2],
                         [2,-6, 8, -6, 2],
                         [-1, 2, -2, 2, -1]])
    # load the image, pre-process it, and store it in the data list
    image = cv2.imread('tiger.bmp',-1)
    gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    myimage = cv2.resize(gray,(256,256))
    myimage = myimage
    print("The image")
    #print(myimage)
    print("That was the image")
    segment = myimage[0:10, 0:10]
    print(segment)

    imgOut = ndimage.convolve(myimage, kernel55)
    #imgOut = imgOut/12
    print(imgOut.shape)
    cv2.imwrite('zzconv.png', imgOut)

    #print(imgOut)
    segment = imgOut[0:10, 0:10]
    print(segment)

    #Build Keras model
    print("And the Keras stuff")
    model = Sequential()
    model.add(Conv2D(1, [5,5], kernel_initializer=kernel_init, input_shape=(256,256,1), padding="same"))
    model.build()

    test_im=myimage
    test_im = test_im.reshape((1, 256, 256, 1))
    print(test_im.shape)
    imgOut2 = model.predict(test_im)
    imgOut2 = imgOut2.reshape(256, 256)
    print(imgOut2.shape)
    #imgOut2 = imgOut2 / 12
    imgOut2[imgOut2 < 0] += 256

    cv2.imwrite('zzconv2.png', imgOut2)

    #print(imgOut2)
    segment = imgOut2[0:10, 0:10]
    print(segment)

Вот что следует отметить:

  • Это изображение, пиксели являются байтами, все, что больше байта, может быть усечено и может быть усечено неправильно(обратите внимание, что мне пришлось удалить ваш "/ 12" в ядре. Вот почему я добавил раздел "+ = 256".
  • Вы не можете предполагать, что "заполненные" области будутполучаются идентичными. Я не знаю, какие значения keras и opencv используют для заполнения, но это не похоже на те же значения. Ваши выходные изображения должны быть идентичны только из [3,3] (то есть граница 3 пикселясо всех сторон может отличаться).
  • Проверьте ваше ядро, прежде чем использовать его. В моей системе оно было округлено до -1 и 0. Предположительно, с использованием целочисленной арифметики. Добавление строки "kernel = kernel / 12" далоболее правильные результаты для ядра, но округление в функции свертки, похоже, опять все испортило, поэтому я оставил его без "/ 12"
  • Relu опять всё испортил, из-заокругление (все, что ниже zero, что keras не корректно урезал до неподписанного байта, отфильтровывался функцией активации).
...