]> AND Private Git Repository - myo-class.git/commitdiff
Logo AND Algorithmique Numérique Distribuée

Private GIT Repository
integrate distinction_word, for deployment
authorBernardo TOD <bernardo.tod52@gmail.com>
Mon, 17 Jun 2019 16:07:49 +0000 (18:07 +0200)
committerBernardo TOD <bernardo.tod52@gmail.com>
Mon, 17 Jun 2019 16:07:49 +0000 (18:07 +0200)
draw.py [new file with mode: 0644]
helpers.py
regularjson.py
reversesample.py [new file with mode: 0644]
test.py [new file with mode: 0644]
topng.py
tosampledir.py
totraindir.py

diff --git a/draw.py b/draw.py
new file mode 100644 (file)
index 0000000..227fd34
--- /dev/null
+++ b/draw.py
@@ -0,0 +1,60 @@
+# import numpy as np
+# import matplotlib.pyplot as plt
+
+# from topng import affine
+
+
+from numpy import exp,arange
+from pylab import meshgrid,cm,imshow,contour,clabel,colorbar,axis,title,show
+
+# the function that I'm going to plot
+def z_func(x,y):
+ return (1-(x**2+y**3))*exp(-(x**2+y**2)/2)
+x = arange(-3.0,3.0,0.1)
+y = arange(-3.0,3.0,0.1)
+X,Y = meshgrid(x, y) # grid of point
+Z = z_func(X, Y) # evaluation of the function on the grid
+
+im = imshow(Z,cmap=cm.RdBu) # drawing the function
+# adding the Contour lines with labels
+cset = contour(Z,arange(-1,1.5,0.2),linewidths=2,cmap=cm.Set2)
+clabel(cset,inline=True,fmt='%1.1f',fontsize=10)
+colorbar(im) # adding the colobar on the right
+# latex fashion title
+title('$z=(1-x^2+y^3) e^{-(x^2+y^2)/2}$')
+show()
+
+
+# dep = ( 0, pow(2, 8) ) # 9 bits
+# arr = ( 0, pow(2, 16) ) # 16 bits
+
+# deprange = np.arange(0, pow(2, 8), 1) # 9 bits
+
+
+# # test <<
+# # plt.plot(dep, arr, 'r--', deprange, deprange<<8, 'bs')
+# # plt.show()
+
+# # print("decalage")
+# # for i in deprange:
+# #    print( 'i, i<<8:', (i, i<<8) )
+# # test >>
+
+# # test <<
+# print("affine transfo")
+# count = 0
+# for i in deprange:
+#      ab = dep
+#      cd = arr
+
+#      a, b = ab[0], ab[1]
+#      c, d = cd[0], cd[1]
+       
+#      r = max( 0, ( (i-a) * (d-c) / (b-a) + c ) )
+#      r2 = i<<8
+#      print( 'i, r:', (i, r) )
+#      print( 'i, i<<8:', (i, r2) )
+#      count += (r != r2)
+
+# print('count', count)
\ No newline at end of file
index 978490042e21d7dcf6dedec72e1462adc907736e..808a4a5adf29b406efaa597c52a27be922f75046 100644 (file)
@@ -1,2 +1,106 @@
+from timeit import timeit
+import numpy as np
+
+
+INPUT_DIR = '../../Data/Images_anonymous/Case_0002/'
+OUT_DIR = './generated/'
+
+
+np.set_printoptions(edgeitems=272, linewidth=500)# hey numpy, take advantage of my large screen
+
+def check(p1, p2, Mat):
+    """
+    Not by @res
+    Uses the line defined by p1 and p2 to check array of 
+    input indices against interpolated value
+
+    Returns boolean array, with True inside and False outside of shape
+    """
+    idxs = np.indices(Mat.shape) # Create 3D array of indices
+
+    try:
+        p1 = p1.astype(float)
+        p2 = p2.astype(float)
+
+        # Calculate max column idx for each row idx based on interpolated line between two points
+        max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) +  p1[1]    
+        sign = np.sign(p2[0] - p1[0])
+        return idxs[1] * sign <= max_col_idx * sign
+    except RuntimeWarning as e:
+        print("p1, p2")
+        print(p1, p2)
+        return True
+
+def drawcontours(Mat, vertices):
+    """
+    Not by @res
+    
+    Mat.shape : (20,20) or something like..
+    vertices : np.array([
+        [5,12],
+        [8,18],
+        [13,14],
+        [11,6],
+        [4,6],
+    ])
+
+    return Mat : the resulting matrix
+    
+    Creates np.array with dimensions defined by shape
+    Fills polygon defined by vertices with ones, all other values zero"""
+
+    fill = np.ones(Mat.shape) # Initialize boolean array defining shape fill
+
+    # Create check array for each edge segment, combine into fill array
+    for k in range(vertices.shape[0]): # .shape[0] is the number of vertices, like len(vertices)
+        fill = np.all([fill, check(vertices[k-1], vertices[k], Mat)], axis=0)
+
+    # Set all values outside polygon to zero
+    # print("fill")
+    # print(fill)
+    Mat[np.invert(fill)] = 0
+
+    return Mat
+
 def getdir(filepath):
-       return '/'.join(filepath.split('/')[:-1]) + '/'
+    return '/'.join(filepath.split('/')[:-1]) + '/'
+
+
+if __name__ == '__main__':
+    # vertices = np.array(list(reversed([
+    #     (5,12),
+    #     (8,18),
+    #     (13,14),
+    #     (11,6),
+    # ]) ))
+
+    vertices = np.array([
+        [ 97, 129],
+        [103, 134],
+        [108, 139],
+        [109, 146],
+        [109, 155],
+        [105, 161],
+        [ 99, 165],
+        [ 93, 166],
+        [ 83, 164],
+        [ 78, 161],
+        [ 73, 153],
+        [ 72, 147],
+        [ 72, 140],
+        [ 75, 133],
+        [ 79, 129],
+        [ 85, 127],
+        [ 93, 127],
+    ])
+
+    from topng import topng
+    Mat = topng(INPUT_DIR+'Image00003', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00003', epimask="/Users/user/Desktop/Master/Stage/Data/json/json_GT/0_Case_0002/contours/1.2.3.4.5.6/31/-85.9968/Epicardic.json")
+    # print(Mat)
+    # Mat = np.ones((20, 25)).astype(np.int32)
+    # Mat[:,:] = 14
+
+    # print( timeit(lambda:create_polygon([20,20], vertices), number=100000) )
+    polygon_array = drawcontours(Mat, vertices)
+    print(polygon_array.shape)
+    # print(polygon_array.astype(np.int32))
index ba7f97e9d1bfe9ce86204d7907e968972fc6707a..87addeb3299f4cef3713e416c38005fb4102aea6 100644 (file)
@@ -21,9 +21,9 @@ from pprint import pprint
 #   |--> json_GT_part2
 RT_PATH = '../../Data/json/'
 JSON_GTS = ['json_GT', 'json_GT_part2']
-INFA_STR = 'Infa'
-EPI_STR = 'Epi'
-ENDO_STR = 'Endo'
+INFA_STR = 'Infarction'
+EPI_STR = 'Epicardic'
+ENDO_STR = 'Endocardic'
 
 # Globals
 featurerefs = []
diff --git a/reversesample.py b/reversesample.py
new file mode 100644 (file)
index 0000000..5b3bb2b
--- /dev/null
@@ -0,0 +1,20 @@
+from os import listdir as ls
+from os.path import join, splitext
+from shutil import move as mv, copyfile as cp
+import pathlib
+
+def move(indir, outdir, n, distinction_word='', copy=True):# move n ordered files from indir to outdir
+       l = sorted(ls(indir))
+       for filename in l[:n]:
+               # print(join(indir, filename), join(outdir, filename))
+               pathlib.Path(outdir).mkdir(parents=True, exist_ok=True)
+               fname, fextension = splitext(filename)
+               action = cp if copy else mv
+               action(join(indir, filename), join(outdir, fname + distinction_word + fextension))
+
+if __name__ == '__main__':
+       
+       move('./sample-crop-mask/train/infarctus', './generated/90/infarctus/crop-mask', 400) # move 400 ordered files from param 1 to param 2
+       move('./sample-crop-mask/train/noinfarctus', './generated/90/noinfarctus/crop-mask', 400)
+       move('./sample-crop-mask/valid/infarctus', './generated/90/infarctus/crop-mask', 100)
+       move('./sample-crop-mask/valid/noinfarctus', './generated/90/noinfarctus/crop-mask', 100)
\ No newline at end of file
diff --git a/test.py b/test.py
new file mode 100644 (file)
index 0000000..dae3446
--- /dev/null
+++ b/test.py
@@ -0,0 +1,89 @@
+from timeit import timeit
+import numpy as np
+
+
+np.set_printoptions(linewidth=500)# hey numpy, take advantage of my large screen
+
+def check(p1, p2, base_array):
+    """
+    Not by @res
+    Uses the line defined by p1 and p2 to check array of 
+    input indices against interpolated value
+
+    Returns boolean array, with True inside and False outside of shape
+    """
+    idxs = np.indices(base_array.shape) # Create 3D array of indices
+
+    p1 = p1.astype(float)
+    p2 = p2.astype(float)
+
+    # Calculate max column idx for each row idx based on interpolated line between two points
+    max_col_idx = (idxs[0] - p1[0]) / (p2[0] - p1[0]) * (p2[1] - p1[1]) +  p1[1]    
+    sign = np.sign(p2[0] - p1[0])
+    return idxs[1] * sign <= max_col_idx * sign
+
+def create_polygon(shape, vertices):
+    """
+    Not by @res
+
+    shape : (20,20)
+    vertices : np.array([
+        (5,12),
+        (8,18),
+        (13,14),
+        (11,6),
+        (4,6),
+    ])
+
+    return base_array : the resulting matrix
+    
+    Creates np.array with dimensions defined by shape
+    Fills polygon defined by vertices with ones, all other values zero"""
+    base_array = np.zeros(shape, dtype=float)  # Initialize your array of zeros
+    base_array[:,:] = 4
+
+    fill = np.ones(base_array.shape)   # Initialize boolean array defining shape fill
+    # print('timeit (base_array.shape) ', timeit( lambda:np.ones(base_array.shape) ))
+    # print('timeit (base_array.shape) * True ', timeit( lambda:np.ones(base_array.shape) * True ))
+    print('base_array.shape', base_array.shape)
+    print('fill.dtype', fill.dtype)
+    print('fill - 1:', fill)
+
+    # Create check array for each edge segment, combine into fill array
+    for k in range(vertices.shape[0]):# .shape[0] is the number of vertices, like len(vertices)
+        fill = np.all([fill, check(vertices[k-1], vertices[k], base_array)], axis=0)
+
+    # Set all values inside polygon to one
+    print("fill:")
+    print(fill)
+    base_array[np.invert(fill)] = 0
+
+    return base_array
+
+
+# (Row, Col) Vertices of Polygon (Defined Clockwise)
+vertices = np.array([
+    (5,12),
+    (8,18),
+    (13,14),
+    (11,6),
+    (4,6),
+])
+
+# print( timeit(lambda:create_polygon([20,20], vertices), number=100000) )
+polygon_array = create_polygon((14,19), vertices)
+print("1)")
+print(polygon_array.astype(np.int32))
+
+# This section prints numbers at each vertex for visual check, just comment out 
+# to print an array of only zeros and ones
+# for n, vertex in enumerate(vertices):
+#     polygon_array[vertex[0],vertex[1]] = 10*(n+1)
+
+# Simple routine to print the final array
+# for row in polygon_array.tolist():
+#     for c in row:
+#         print( '{:4.1f}'.format(c) )
+#     print()
+# print("2)")
+# print(polygon_array.astype(np.int32))
\ No newline at end of file
index 8722d98c785f756ab87452b1574fb0d97966fa3c..fde569ba6509bdf19efb0a28c282d4ec4b8b1dfb 100644 (file)
--- a/topng.py
+++ b/topng.py
@@ -2,36 +2,52 @@ import cv2
 import os
 from os.path import isdir, join
 from os import mkdir
+from timeit import timeit
 import pydicom
 from pprint import pprint
 import numpy as np
 import pathlib
 import json
 
+from scipy import ndimage
+from scipy import misc
+
+
 from decimal import Decimal as d, ROUND_HALF_UP as rhu
 
+# locals
+from helpers import drawcontours
+
+np.set_printoptions(edgeitems=372, linewidth=1200)# hey numpy, take advantage of my large screen
+
 PNG16_MAX = pow(2, 16) - 1 # here if thinks the heaviest weight bit is for transparency or something not in use with dicom imgs
 PNG8_MAX = pow(2, 8+1) - 1 # heaviest weight bit is 8 => 2**8, but dont forget the others: the reason of +1
 
 INPUT_DIR = '../../Data/Images_anonymous/Case_0002/'
 OUT_DIR = './generated/'
-#os.mkdir(outdir)
+
+CROP_SIZE = (45, 45) # (width, height)
+RED_COLOR = 100
 
 def roundall(*l):
-       return (round(e) for e in l)
+       return (int(round(e)) for e in l)
 
 def ftrim(Mat):
+       # ---------- FTRIM ----------
        # private func to trim the Matrix, but in one direction, vertically | horizontally
        # return the slice, don't affect the Matrix
-       # y | : for column, x -> : for rows
+       # y | : for (top to bottom), x -> : for (left to right)
        #   v
        # not my fault, numpy architecture
+
        y1 = y2 = i = 0
+
        while i < len(Mat):# search by top
                if Mat[i].max() > 0:
                        y1 = i
                        break
                i += 1
+
        i = len(Mat) - 1
        while i >= 0:# search by bottom
                if Mat[i].max() > 0:
@@ -48,29 +64,8 @@ def trim(Mat):
        # print('horizontal:vertical', horizontal, vertical)
        return Mat[horizontal, vertical]
 
-def mask(Mat, maskfile):
-       # return
-       xmin, ymin, xmax, ymax = minmax(Mat, maskfile)
-
-       y1 = y2 = i = 0
-       while i < len(Mat):# search by top
-               if i < ymin: 
-                       Mat[i].fill(0)# paint the row in black
-               else: break
-               i += 1
-       
-       i = len(Mat) - 1
-       while i >= 0:# search by bottom
-               if i > ymax:
-                       Mat[i].fill(0)# paint the row in black
-               else: break
-               i -= 1
-       # print('y1, y2', y1, y2)
-       # return slice(y1, y2+1)# +1 to stop at y2
-
-
 
-def minmax(Mat, file):
+def getxy(file):
        """
                {
                        'Image00001': [{
@@ -93,35 +88,170 @@ def minmax(Mat, file):
                                ]
                        }]
                }
-               return xmin, ymin, xmax, ymax
+               return [(94.377, 137.39), ...]
        """
        with open(file) as jsonfile:
                data = json.load(jsonfile)
-               pprint(data)
-               
-               for imgXXX in data:pass # get the value of key ~= "Image00001", cause it's dynamic
-               
-               for obj in data[imgXXX]:pass # get the object that contains the points, cause it's a list
-               points = obj['points']
+               # pprint(data)
+
+               for imgXXX in data: pass  # get the value of key ~= "Image00001", cause it's dynamic
 
+               for obj in data[imgXXX]: pass  # get the object that contains the points, cause it's a list
+               points = obj['points']
 
                # print("print, ", data)
                # print("imgXXX, ", imgXXX)
                # print("points, ", points)
                # print("imgXXX, ", obj['points'])
-               tmp = [(pt['x'], pt['y']) for pt in points ] # extract x,y. {'x': 94.377, 'y': 137.39} => (94.377, 137.39)
-               r = np.array(tmp)
-
-               print(r) # log
-
+               tmp = [np.array( (round(pt['x']), round(pt['y'])) ).astype(np.int32) for pt in
+                          points]  # extract x,y. {'x': 94.377, 'y': 137.39} => (94.377, 137.39)
+               return np.array(tmp, dtype=np.int32)
+               # return tmp
+
+def minmax(file):
+       r = getxy(file)
+       if r is not None:
+               # print(r) # log
                xmin, ymin = np.min(r, axis=0)
                xmax, ymax = np.max(r, axis=0)
 
-               print('xmax, ymax', xmax, ymax)
-               print('xmin, ymin', xmin, ymin)
+               print('xmax, ymax', xmax, ymax)
+               print('xmin, ymin', xmin, ymin)
 
                return roundall(xmin, ymin, xmax, ymax)
 
+def crop(Mat, maskfile, size=None):
+       """
+               size : if filled with a (45, 45), it will search the center of maskfile then crop by center Mat
+       """
+       xmin, ymin, xmax, ymax = minmax(maskfile)
+       if size:
+               xcenter = (xmin + xmax) / 2
+               ycenter = (ymin + ymax) / 2
+
+               # crop coords
+               ymin, xmin, ymax, xmax = roundall(xcenter - size[0], ycenter - size[0],
+                                                                 xcenter + size[1], ycenter + size[1])
+
+       return Mat[xmin:xmax, ymin:ymax]
+
+def contour(Mat, maskfiles, color, thickness=1):
+       # ---------- CONTOUR POLYGON ----------
+       # thickness = -1 => fill it
+       #                       = 1 => just draw the contour with color
+       #
+       # return new Mat
+       contours = [getxy(maskfile) for maskfile in maskfiles] # list of list of coords, 
+       # [ 
+       #       [ (3,43), (3,4) ],
+       #       [ (33,43) ]
+       # ]
+       # print("log: contours", contours)
+       if contours is not None:
+               # print('type contours', type(contours))
+               # print('contours', contours)
+               msk = np.zeros(Mat.shape, dtype=np.int32) # init all the mask with True... 
+               cv2.drawContours(msk, contours, -1, True, thickness) # affect Mat, fill the polygone with False
+               msk = msk.astype(np.bool)
+               # print('msk')
+               # print(msk)
+               # print("bool", timeit(lambda:msk, number=1000))
+               # print("normal", timeit(lambda:msk.astype(np.bool), number=1000))
+               # Mat = cv2.cvtColor(Mat, cv2.COLOR_RGB2GRAY) # apply gray
+
+               # Mat = drawcontours(Mat, contours)
+               # pass
+               Mat[msk] = color # each True in msk means 0 in Mat. msk is like a selector
+       return Mat
+
+def mask(Mat, maskfile, color=0, thickness=-1):
+       # ---------- MASK POLYGON ----------
+       # thickness = -1 => fill it
+       #                       = 1 => just draw the contour with color
+       #
+       # return new Mat
+       contours = getxy(maskfile)
+       # print("log: contours", contours)
+       if contours is not None:
+               # print('type contours', type(contours))
+               # print('contours', contours)
+               msk = np.ones(Mat.shape, dtype=np.int32) # init all the mask with True... 
+               cv2.drawContours(msk, [contours], -1, False, thickness) # affect msk, fill the polygone with False, => further, don't touch where is False
+               msk = msk.astype(np.bool)
+               # print('msk')
+               # print(msk)
+               # print("bool", timeit(lambda:msk, number=1000))
+               # print("normal", timeit(lambda:msk.astype(np.bool), number=1000))
+               # Mat = cv2.cvtColor(Mat, cv2.COLOR_RGB2GRAY) # apply gray
+
+               # Mat = drawcontours(Mat, contours)
+               # pass
+               Mat[msk] = color # each True in msk means 0 in Mat. msk is like a selector
+       return Mat
+
+
+def hollowmask(Mat, epifile, endofile, color=0, thickness=-1):
+       # ---------- MASK POLYGON ----------
+       # thickness = -1 => fill it
+       #                       = 1 => just draw the contour with color
+       #
+       # return new Mat
+       epicontours = getxy(epifile)
+       endocontours = getxy(endofile)
+       if epicontours is not None and endocontours is not None:
+               msk = np.ones(Mat.shape, dtype=np.int32) # init all the mask with True... 
+               cv2.drawContours(msk, [epicontours], -1, False, thickness) # affect msk, fill the polygone with False, => further, don't touch where is False
+               cv2.drawContours(msk, [endocontours], -1, True, thickness) #                     fill the intern polygone with True, (the holow in the larger polygon), => further, color where is True with black for example
+               msk = msk.astype(np.bool)
+               
+               Mat[msk] = color # each True in msk means 0 in Mat. msk is like a selector
+       return Mat
+
+
+def sqrmask1(Mat, maskfile):
+       # ---------- SQUARE MASK 1st approach ----------
+       # print( timeit( lambda:sqrmask1(img, epimask), number=1000 ) ) # 0.48110522600000005
+       # return new Mat
+       xmin, ymin, xmax, ymax = minmax(maskfile)
+       # print("xmin, ymin, xmax, ymax", xmin, ymin, xmax, ymax)
+
+       i = 0
+       while i < ymin:# search by top
+               Mat[i].fill(0)# paint the row in black
+               i += 1
+       
+       i = len(Mat) - 1
+       while i > ymax:# search by bottom
+               Mat[i].fill(0)# paint the row in black
+               i -= 1
+
+       i = 0
+       while i < xmin:# search by top
+               Mat.T[i, ymin:ymax+1].fill(0) # paint the column (row of the Transpose) in black, ymin and ymax to optimize, cause, I previously painted a part
+               i += 1
+
+       i = len(Mat.T) - 1
+       while i > xmax:# search by bottom
+               Mat.T[i, ymin:ymax+1].fill(0) # paint the column (row of the Transpose) in black, ymin and ymax to optimize, cause, I previously painted a part
+               i -= 1
+
+       return Mat
+
+def sqrmask2(Mat, maskfile):
+       # ---------- SQUARE MASK 2nd and best approach ----------
+       # print( timeit( lambda:sqrmask2(img, epimask), number=1000 ) ) # 0.3097705270000001
+       # return new Mat
+       xmin, ymin, xmax, ymax = minmax(maskfile)
+       # print("xmin, ymin, xmax, ymax", xmin, ymin, xmax, ymax)
+
+       msk = np.ones(Mat.shape, dtype=np.int32) # init all the mask with True... 
+       msk = msk.astype(np.bool)
+
+       msk[ymin:ymax, xmin:xmax] = False # for after, don't touch between min and max region
+       Mat[msk] = 0
+
+       return Mat
+
 def map16(array):# can be useful in future
        return array * 16
 
@@ -145,17 +275,31 @@ def affine(Mat, ab, cd):
 def getdir(filepath):
        return '/'.join(filepath.split('/')[:-1]) + '/'
 
-def topng(inputfile, outfile=None, overwrite=True, verbose=False):
+def readpng(inputfile):# just a specific func to preview a "shape = (X,Y,3)" image
+       image = misc.imread(inputfile)
+
+       print("image")
+       print("image.shape", image.shape)
+
+       for tab in image:
+               for i, row in enumerate(tab):
+                       print(row[0]*65536 + row[0]*256 + row[0], end=" " if i % image.shape[0] != 0 else "\n")
+
+def topng(inputfile, outfile=None, overwrite=True, verbose=False, epimask='', endomask='', centercrop=None, blackmask=False, square=False, redcontour=False):
        """
                (verbose) return (64, 64) : the width and height
                (not verbose) return (img, dicimg) : the image and the dicimg objects
+               centercrop : it's a size (45, 45), to mention I want to crop by center of epimask and by size.
+               blackmask : draw the outside with black
+
        """
        try:
                dicimg = pydicom.read_file(inputfile) # read dicom image
        except pydicom.errors.InvalidDicomError as e:
                # @TODO: log, i can't read this file
                return
-       img = trim(dicimg.pixel_array)# get image array (12bits)
+       # img = trim(dicimg.pixel_array)# get image array (12bits), Don't trim FOR THE MOMENT
+       img = dicimg.pixel_array# get image array (12bits)
 
        # test <<
        # return img.shape # $$ COMMENT OR REMOVE THIS LINE 
@@ -170,14 +314,52 @@ def topng(inputfile, outfile=None, overwrite=True, verbose=False):
 
        # affine transfo to png 16 bits, func affects img variable
        maxdepth = pow(2, dicimg.BitsStored) - 1
-       print('dicimg.BitsStored, (img.min(), img.max())', dicimg.BitsStored, (img.min(), img.max())) # testing..
+       # print('dicimg.BitsStored, (img.min(), img.max())', dicimg.BitsStored, (img.min(), img.max())) # testing..
+       if int(dicimg.BitsStored) < 12:
+               print("\n\n\n-----{} Bits-----\n\n\n\n".format(dicimg.BitsStored))
        affine(img, 
                (0, maxdepth), # img.min() replace 0 may be, but not sure it would be good choice
                (0, PNG16_MAX if maxdepth > PNG8_MAX else PNG8_MAX)
        )
        
-       mask(img, '/Users/user/Desktop/Master/Stage/Data/json/json_GT/0_Case_0002/contours/1.2.3.4.5.6/31/-85.9968/Epicardic.json')
+       # test <<
+       # imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
+       # ret,thresh = cv2.threshold(img,127,255,0)
+       # im2, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
+       # print("im2, contours, hierarchy", im2, contours, hierarchy)
+       # test >>
+
+       # return img
+
+       # print("log: epimask", epimask)
+
+       if epimask:
+               if redcontour:
+                       
+                       contours = [epimask] # list of list of coords 
+                       if endomask:contours.append(endomask)
 
+                       img = contour(img, contours, color=RED_COLOR, thickness=1)
+
+               if blackmask:# if is there a mask => apply
+                       if square:
+                               img = sqrmask2(img, epimask)
+                       else:
+                               if endomask:
+                                       img = hollowmask(img, epimask, endomask)
+                               else:
+                                       img = mask(img, epimask)
+
+               if centercrop:
+                       img = crop(img, epimask, centercrop)
+
+
+       # return
+       # test
+       # if verbose:
+       #       return img, dicimg, minmax(epimask)
+       # else:
+       #       return img.shape
 
        savepath = (outfile or inputfile) + '.png'
        savedir = getdir(savepath)
@@ -194,11 +376,17 @@ def topng(inputfile, outfile=None, overwrite=True, verbose=False):
        # np.savetxt(savepath + '.npy', img)
        # test >>
 
-       cv2.imwrite(savepath, img, [cv2.IMWRITE_PNG_COMPRESSION, 0]) # write png image
+       if np.count_nonzero(img) > 0: # matrix not full of zero
+               cv2.imwrite(savepath, img, [cv2.IMWRITE_PNG_COMPRESSION, 0]) # write png image
+
+       # print("ndimage.imread(savepath)", ndimage.imread(savepath).shape)
+       # print( ndimage.imread(savepath) )
+       # print("np.expand_dims(ndimage.imread(savepath), 0)", np.expand_dims(ndimage.imread(savepath), 0).shape)
+       # print(np.expand_dims(ndimage.imread(savepath), 0))
 
        # test
        if verbose:
-               return img, dicimg
+               return img, dicimg, minmax(epimask)
        else:
                return img.shape
 
@@ -213,4 +401,5 @@ def topngs(inputdir, outdir):
 
 if __name__ == '__main__':
        # topngs( INPUT_DIR, join(OUT_DIR, INPUT_DIR.split('/')[-2]) )
-       topng(INPUT_DIR+'Image00003', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00003')
+       readpng(OUT_DIR+'aug_circle.png')
+       # topng(INPUT_DIR+'Image00003', OUT_DIR + INPUT_DIR.split('/')[-2] +'-Image00003', epimask="/Users/user/Desktop/Master/Stage/Data/json/json_GT/0_Case_0002/contours/1.2.3.4.5.6/31/-85.9968/Epicardic.json")
index 87effac8fbb55cdd6dd382333cabbb3ad712b3fb..1846c1d10a7f5764450d425288f18162fabb12a5 100644 (file)
@@ -1,18 +1,20 @@
 from os import listdir as ls
-from os.path import join
-from shutil import move as mv
+from os.path import join, splitext
+from shutil import move as mv, copyfile as cp
 import pathlib
 
-def move(indir, outdir, n):# move n ordered files from indir to outdir
+def move(indir, outdir, n, distinction_word='', copy=True):# move n ordered files from indir to outdir
        l = sorted(ls(indir))
        for filename in l[:n]:
                # print(join(indir, filename), join(outdir, filename))
                pathlib.Path(outdir).mkdir(parents=True, exist_ok=True)
-               mv(join(indir, filename), join(outdir, filename))
+               fname, fextension = splitext(filename)
+               action = cp if copy else mv
+               action(join(indir, filename), join(outdir, fname + distinction_word + fextension)) # distinction_word='-mask'; /path/file.jpg => /path/file-mask.jpg
 
 if __name__ == '__main__':
        
-       move('./train/infarctus', './sample/train/infarctus', 1000) # move 1000 ordered files from param 1 to param 2
-       move('./train/noinfarctus', './sample/train/noinfarctus', 1000)
-       move('./train/infarctus', './sample/valid/infarctus', 300)
-       move('./train/noinfarctus', './sample/valid/noinfarctus', 300)
\ No newline at end of file
+       move('./generated/90/infarctus/crop-nomask', './sample/train/infarctus', 400, distinction_word="-crop-nomask") # move 400 ordered files from param 1 to param 2
+       move('./generated/90/noinfarctus/crop-nomask', './sample/train/noinfarctus', 400, distinction_word="-crop-nomask")
+       move('./generated/90/infarctus/crop-nomask', './sample/valid/infarctus', 100, distinction_word="-crop-nomask")
+       move('./generated/90/noinfarctus/crop-nomask', './sample/valid/noinfarctus', 100, distinction_word="-crop-nomask")
\ No newline at end of file
index 1fbaf08481a790594b088fe442c69e71ae9651c8..b901b85bb7ea34c22bf7730eb83f58f8327e717d 100644 (file)
@@ -4,12 +4,12 @@ import pydicom
 from os.path import join
 
 # locals
-from topng import topng, mask
-from regularjson import search, RT_PATH, JSON_GTS, INFA_STR, EPI_STR
+from topng import topng, mask, CROP_SIZE
+from regularjson import search, RT_PATH, JSON_GTS, INFA_STR, EPI_STR, ENDO_STR
 
 # constants
 GLOB_DIR = '../../Data/Images_anonymous/'
-OUT_DIR = './generated/train/'
+OUT_DIR = './generated/90/'
 INDICE_CASE = 'Case'
 
 START = None # to manage the number of Patient Case to use in training + validation, if START == None => 0, if END == None => last index, it will use all in GLOB_DIR
@@ -65,27 +65,95 @@ if __name__ == '__main__':
 
                        for i, dic in enumerate(l1):
                                # print('join', r, l2[i])
-                               ref = join(r, l2[i]) # logically, should be the json ref of i dicom image
+                               ref = join(r, l2[i]) # logically, should be the json ref's "parent directory" of i dicom image
 
                                infarctus = search(ref, INFA_STR)
-                               # epimask = mask(ref, EPI_STR)
+                               epimask = search(ref, EPI_STR)
+                               endomask = search(ref, ENDO_STR)
+                               # print("ref left:", l1[i]) # Testing..
+                               # print("ref right:", ref) # Testing..
                                # print("infarctus:", infarctus) # Testing..
                                # topng(join(caspath, dic), '%/%-%' % (join(OUT_DIR, 'infarctus'), cas, dic)
-                               w, h = topng(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'infarctus' if infarctus else 'noinfarctus'), cas, dic))
-
-                               # search maximums
-                               if wmax < w: wmax = w 
-                               if hmax < h: hmax = h
-
-                               # search width minimum
-                               if wmin is None: wmin = w
-                               elif wmin > w: wmin = w
-                               
-                               # search height minimum
-                               if hmin is None: hmin = h
-                               elif hmin > h: hmin = h
-
-       print('min-width, max-width:', (wmin, wmax))
-       print('min-height, max-height:', (hmin, hmax))
-
-       print('Ended!')
+                               # print('epimask', epimask)
+
+                               if epimask:# this condition could be if necessary
+                                       # w, h = topng(join(caspath, dic), '{}/{}-{}'.format(join(OUT_DIR, 'infarctus' if infarctus else 'noinfarctus'), cas, dic), epimask=epimask['path'] if epimask else None)
+                                       # img_, dicimg_, minmax_ = topng(join(caspath, dic),
+                                       #       '{}/{}-{}'.format(join(OUT_DIR, 'infarctus' if infarctus else 'noinfarctus'), cas, dic),
+                                       #       epimask=epimask['path'] if epimask else None,
+                                       #       verbose=True,
+                                       # )
+
+                                       # Possibly data augmentation purpose here
+                                       w, h = topng(
+                                               join(caspath, dic),
+                                               outfile='{}/crop-mask/{}-{}'.format(join(OUT_DIR,
+                                                       'infarctus' if infarctus else 'noinfarctus'),
+                                                       cas,
+                                                       dic,
+                                               ),
+                                               epimask=epimask['path'] if epimask else None,
+                                               centercrop=CROP_SIZE,
+                                               blackmask=True,
+                                       ) # crop and mask with black
+
+                                       if endomask:
+                                               w, h = topng(
+                                                       join(caspath, dic),
+                                                       outfile='{}/crop-mask-hollow/{}-{}'.format(join(OUT_DIR,
+                                                               'infarctus' if infarctus else 'noinfarctus'),
+                                                               cas,
+                                                               dic,
+                                                       ),
+                                                       epimask=epimask['path'] if epimask else None,
+                                                       endomask=endomask['path'] if endomask else None,
+                                                       centercrop=CROP_SIZE,
+                                                       blackmask=True,
+                                               ) # crop and (mask and fill hollow) with black
+
+                                       w, h = topng(
+                                               join(caspath, dic),
+                                               outfile='{}/crop-nomask/{}-{}'.format(join(OUT_DIR,
+                                                       'infarctus' if infarctus else 'noinfarctus'),
+                                                       cas,
+                                                       dic,
+                                               ),
+                                               epimask=epimask['path'] if epimask else None,
+                                               centercrop=CROP_SIZE,
+                                       ) # just crop, don't apply black mask
+
+                                       # w, h = topng(
+                                       #       join(caspath, dic),
+                                       #       outfile='{}/contour/{}-{}'.format(join(OUT_DIR,
+                                       #               'infarctus' if infarctus else 'noinfarctus'),
+                                       #               cas,
+                                       #               dic,
+                                       #       ),
+                                       #       epimask=epimask['path'] if epimask else None,
+                                       #       redcontour=True,
+                                       # ) # draw a red contour for visibily purpose
+
+                                       # segmentation width & height <<
+                                       # xmin, ymin, xmax, ymax = minmax_
+                                       # w = xmax - xmin + 1 # +1 : even the position takes a bit
+                                       # h = ymax - ymin + 1
+                                       # segmentation width & height >>
+
+
+                                       # # search maximums
+                                       # if wmax < w: wmax = w 
+                                       # if hmax < h: hmax = h
+
+                                       # # search width minimum
+                                       # if wmin is None: wmin = w
+                                       # elif wmin > w: wmin = w
+                                       
+                                       # # search height minimum
+                                       # if hmin is None: hmin = h
+                                       # elif hmin > h: hmin = h
+
+
+       # print('min-width, max-width:', (wmin, wmax))
+       # print('min-height, max-height:', (hmin, hmax))
+
+       # print('Ended!')