]> 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):
 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']
 #   |--> 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 = []
 
 # 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
 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
 
 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
 
 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/'
 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):
 
 def roundall(*l):
-       return (round(e) for e in l)
+       return (int(round(e)) for e in l)
 
 def ftrim(Mat):
 
 def ftrim(Mat):
+       # ---------- FTRIM ----------
        # private func to trim the Matrix, but in one direction, vertically | horizontally
        # return the slice, don't affect the Matrix
        # 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
        #   v
        # not my fault, numpy architecture
+
        y1 = y2 = i = 0
        y1 = y2 = i = 0
+
        while i < len(Mat):# search by top
                if Mat[i].max() > 0:
                        y1 = i
                        break
                i += 1
        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:
        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]
 
        # 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': [{
        """
                {
                        '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)
        """
        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'])
 
                # 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)
 
                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)
 
 
                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
 
 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 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
        """
                (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
        """
        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 
 
        # 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
 
        # 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)
        )
        
        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)
 
        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 >>
 
        # 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:
 
        # test
        if verbose:
-               return img, dicimg
+               return img, dicimg, minmax(epimask)
        else:
                return img.shape
 
        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]) )
 
 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 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
 
 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)
        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__':
        
 
 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 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/'
 
 # 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
 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])
 
                        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)
 
                                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)
                                # 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!')