2016-07-06 2 views
2

이것은 길쌈 신경 네트워크 및 Tensorflow를 처음 사용하는 것입니다.Tensorflow 시작하기 - 하위 이미지로 이미지 분할

디지털 망막 이미지에서 혈관을 추출 할 수있는 길쌈 신경망을 구현하려고합니다. 공개적으로 사용 가능한 Drive database (이미지는 .tif 형식)으로 작업하고 있습니다.

내 이미지가 크기 때문에 28x28x1 크기의 하위 이미지로 분할하는 것이 좋습니다 ("1"은 필요한 녹색 채널입니다). 교육 세트를 만들려면 각 이미지에서 반복적으로 28x28 배치를 자르고이 세트로 네트워크를 훈련 시키십시오.

이제 데이터베이스의 큰 이미지 중 하나에서 훈련 된 네트워크를 테스트하고 싶습니다. 즉, 완전한 눈에 네트워크를 적용하고 싶습니다.

Fig1

: 내 네트워크가 크기 28x28의 서브 이미지에 대한 교육을하기 때문에 생각은, 'N'서브 이미지에 눈을 분할 그들이 네트워크를 던져 통과를 재 조립하고, 필립스의 쇼와 같은 결과를 보여주는 것입니다

tf.extract_image_pathces 또는 tf.train.batch과 같은 일부 기능을 사용해 보았습니다. 그러나이 작업을 수행하는 데 올바른 방법이 무엇인지 알고 싶습니다.

다음은 내 코드 스 니펫입니다. 내가 끼 었어 기능은 split_image(image)

import numpy 
import os 
import random 

from PIL import Image 
import tensorflow as tf 

BATCH_WIDTH = 28; 
BATCH_HEIGHT = 28; 

NUM_TRIALS = 10; 

class Drive: 
    def __init__(self,train): 
     self.train = train 

class Dataset: 
    def __init__(self, inputs, labels): 
     self.inputs = inputs 
     self.labels = labels 
     self.current_batch = 0 

    def next_batch(self): 
     batch = self.inputs[self.current_batch], self.labels[self.current_batch] 
     self.current_batch = (self.current_batch + 1) % len(self.inputs) 
     return batch 


#counts the number of black pixel in the batch 
def mostlyBlack(image): 
    pixels = image.getdata() 
    black_thresh = 50 
    nblack = 0 
    for pixel in pixels: 
     if pixel < black_thresh: 
      nblack += 1 

    return nblack/float(len(pixels)) > 0.5 

#crop the image starting from a random point 
def cropImage(image, label): 
    width = image.size[0] 
    height = image.size[1] 
    x = random.randrange(0, width - BATCH_WIDTH) 
    y = random.randrange(0, height - BATCH_HEIGHT) 
    image = image.crop((x, y, x + BATCH_WIDTH, y + BATCH_HEIGHT)).split()[1] 
    label = label.crop((x, y, x + BATCH_WIDTH, y + BATCH_HEIGHT)).split()[0] 
    return image, label 

def split_image(image): 

    ksizes_ = [1, BATCH_WIDTH, BATCH_HEIGHT, 1] 
    strides_ = [1, BATCH_WIDTH, BATCH_HEIGHT, 1] 

    input = numpy.array(image.split()[1]) 
    #input = tf.reshape((input), [image.size[0], image.size[1]]) 

    #input = tf.train.batch([input],batch_size=1) 
    split = tf.extract_image_patches(input, padding='VALID', ksizes=ksizes_, strides=strides_, rates=[1,28,28,1], name="asdk") 

#creates NUM_TRIALS images from a dataset 
def create_dataset(images_path, label_path): 
    files = os.listdir(images_path) 
    label_files = os.listdir(label_path) 

    images = []; 
    labels = []; 
    t = 0 
    while t < NUM_TRIALS: 
     index = random.randrange(0, len(files)) 
     if files[index].endswith(".tif"): 
      image_filename = images_path + files[index] 
      label_filename = label_path + label_files[index] 
      image = Image.open(image_filename) 
      label = Image.open(label_filename) 
      image, label = cropImage(image, label) 
      if not mostlyBlack(image): 
       #images.append(tf.convert_to_tensor(numpy.array(image))) 
       #labels.append(tf.convert_to_tensor(numpy.array(label))) 
       images.append(numpy.array(image)) 
       labels.append(numpy.array(label)) 

       t+=1 

    image = Image.open(images_path + files[1]) 
    split_image(image) 

    train = Dataset(images, labels) 
    return Drive(train) 
+1

나는 패치와 혼란스럽지 않은 배치를 의미한다고 생각합니다. – jean

답변

1

당신은 타일로 이미지 잘라 reshapetranspose 통화의 조합을 사용할 수 있습니다 : image3은 3 차원 텐서입니다

def split_image(image3, tile_size): 
    image_shape = tf.shape(image3) 
    tile_rows = tf.reshape(image3, [image_shape[0], -1, tile_size[1], image_shape[2]]) 
    serial_tiles = tf.transpose(tile_rows, [1, 0, 2, 3]) 
    return tf.reshape(serial_tiles, [-1, tile_size[1], tile_size[0], image_shape[2]]) 

(예 : 이미지)이고 tile_size은 타일 크기를 지정하는 값 쌍인 [H, W]입니다. 출력은 모양이 [B, H, W, C] 인 텐서입니다. 귀하의 경우에는 호출은 다음과 같습니다

tiles = split_image(image, [28, 28]) 

모양 [B, 28, 28, 1]와 텐서의 결과. 또한 역으로 이러한 작업을 수행하여 타일 원본 이미지를 재 조립 할 수 있습니다

def unsplit_image(tiles4, image_shape): 
    tile_width = tf.shape(tiles4)[1] 
    serialized_tiles = tf.reshape(tiles4, [-1, image_shape[0], tile_width, image_shape[2]]) 
    rowwise_tiles = tf.transpose(serialized_tiles, [1, 0, 2, 3]) 
    return tf.reshape(rowwise_tiles, [image_shape[0], image_shape[1], image_shape[2]])) 
tiles4 모양 [B, H, W, C]의 4D 텐서이다

하고 image_shape 원본 이미지의 모양이다. 귀하의 경우에는 통화가 될 수있다 : 이미지 크기는 타일 크기로 나누어있을 경우에만 작동

image = unsplit_image(tiles, tf.shape(image)) 

하는 것으로.

def pad_image_to_tile_multiple(image3, tile_size, padding="CONSTANT"): 
    imagesize = tf.shape(image3)[0:2] 
    padding_ = tf.to_int32(tf.ceil(imagesize/tile_size)) * tile_size - imagesize 
    return tf.pad(image3, [[0, padding_[0]], [0, padding_[1]], [0, 0]], padding) 

당신과 같은 부를 것이다 : 그건 당신이 패드에 타일 크기의 가장 가까운 배수로 이미지 필요한 경우가 아니라면

image = pad_image_to_tile_multiple(image, [28,28]) 

그런 다음 접합하여 paddig 제거를하면 재 조립 후 타일에서 이미지 :

image = image[0:original_size[0], 0:original_size[1], :]