flux-fill-outpaint / trimap_module.py
nuwandaa's picture
Update trimap_module.py
9c7406f verified
#!/usr/bin/env python
import cv2, os, sys
import numpy as np
def extractImage(path):
# error handller if the intended path is not found
image = cv2.imread(path, cv2.IMREAD_GRAYSCALE)
return image
def checkImage(image):
"""
Args:
image: input image to be checked
Returns:
binary image
Raises:
RGB image, grayscale image, all-black, and all-white image
"""
if len(image.shape) > 2:
print("ERROR: non-binary image (RGB)"); sys.exit();
smallest = image.min(axis=0).min(axis=0) # lowest pixel value: 0 (black)
largest = image.max(axis=0).max(axis=0) # highest pixel value: 1 (white)
if (smallest == 0 and largest == 0):
print("ERROR: non-binary image (all black)"); sys.exit()
elif (smallest == 255 and largest == 255):
print("ERROR: non-binary image (all white)"); sys.exit()
elif (smallest > 0 or largest < 255 ):
print("ERROR: non-binary image (grayscale)"); sys.exit()
else:
return True
class Toolbox:
def __init__(self, image):
self.image = image
@property
def printImage(self):
"""
Print image into a file for checking purpose
unitTest = Toolbox(image);
unitTest.printImage(image);
"""
f = open("image_results.dat", "w+")
for i in range(0, self.image.shape[0]):
for j in range(0, self.image.shape[1]):
f.write("%d " %self.image[i,j])
f.write("\n")
f.close()
@property
def displayImage(self):
"""
Display the image on a window
Press any key to exit
"""
cv2.imshow('Displayed Image', self.image)
cv2.waitKey(0)
cv2.destroyAllWindows()
def saveImage(self, title, extension):
"""
Save as a specific image format (bmp, png, or jpeg)
"""
cv2.imwrite("{}.{}".format(title,extension), self.image)
def morph_open(self, image, kernel):
"""
Remove all white noises or speckles outside images
Need to tune the kernel size
Instruction:
unit01 = Toolbox(image);
kernel = np.ones( (9,9), np.uint8 );
morph = unit01.morph_open(input_image, kernel);
"""
bin_open = cv2.morphologyEx(self.image, cv2.MORPH_OPEN, kernel)
return bin_open
def morph_close(self, image, kernel):
"""
Remove all black noises or speckles inside images
Need to tune the kernel size
Instruction:
unit01 = Toolbox(image);
kernel = np.ones( (11,11)_, np.uint8 );
morph = unit01.morph_close(input_image, kernel);
"""
bin_close = cv2.morphologyEx(self.image, cv2.MORPH_CLOSE, kernel)
return bin_close
def trimap(image, name, size, number, erosion=False):
"""
This function creates a trimap based on simple dilation algorithm
Inputs [4]: a binary image (black & white only), name of the image, dilation pixels
the last argument is optional; i.e., how many iterations will the image get eroded
Output : a trimap
"""
checkImage(image)
row = image.shape[0]
col = image.shape[1]
pixels = 2*size + 1 ## Double and plus 1 to have an odd-sized kernel
kernel = np.ones((pixels,pixels),np.uint8) ## Pixel of extension I get
if erosion is not False:
erosion = int(erosion)
erosion_kernel = np.ones((3,3), np.uint8) ## Design an odd-sized erosion kernel
image = cv2.erode(image, erosion_kernel, iterations=erosion) ## How many erosion do you expect
image = np.where(image > 0, 255, image) ## Any gray-clored pixel becomes white (smoothing)
# Error-handler to prevent entire foreground annihilation
if cv2.countNonZero(image) == 0:
print("ERROR: foreground has been entirely eroded")
sys.exit()
dilation = cv2.dilate(image, kernel, iterations = 1)
dilation = np.where(dilation == 255, 127, dilation) ## WHITE to GRAY
remake = np.where(dilation != 127, 0, dilation) ## Smoothing
remake = np.where(image > 127, 200, dilation) ## mark the tumor inside GRAY
remake = np.where(remake < 127, 0, remake) ## Embelishment
remake = np.where(remake > 200, 0, remake) ## Embelishment
remake = np.where(remake == 200, 255, remake) ## GRAY to WHITE
#############################################
# Ensures only three pixel values available #
# TODO: Optimization with Cython #
#############################################
for i in range(0,row):
for j in range (0,col):
if (remake[i,j] != 0 and remake[i,j] != 255):
remake[i,j] = 127
return remake
#############################################
### TESTING SECTION ###
#############################################
if __name__ == '__main__':
path = "./images/test_images/test_image_11.png"
image = extractImage(path)
size = 10
number = path[-5]
title = "test_image"
unit01 = Toolbox(image);
kernel1 = np.ones( (11,11), np.uint8 )
unit01.displayImage
opening = unit01.morph_close(image,kernel1)
trimap(opening, title, size, number, erosion=False)
unit02 = Toolbox(opening)
unit02.displayImage
########################################################
## Default instruction (no binary opening or closing ##
## trimap(image, title, size, number, erosion=False); ##
########################################################