-4

My work requires applying Local Binary Operator on Images. For that I have already converted the images in Gray then implemented a Connected Components analysis on the image also.

Here is the Code:

  1. Adding Libraries

     import numpy as np
     import pandas as pd
     import matplotlib.pyplot as plt
     from skimage.io import imread, imshow
     from skimage.color import rgb2gray
     from skimage.morphology import (erosion, dilation, closing, opening,area_closing, area_opening)
     from skimage.measure import label, regionprops, regionprops_table
    
  2. Rendering the image

     plt.figure(figsize=(6,6))
     painting = imread("E:/Project/for_annotation/Gupi Gain0032.jpg")
     plt.imshow(painting);
    
     plt.figure(figsize=(6,6))
    
  3. Binarizing Image

     gray_painting = rgb2gray(painting)
     binarized = gray_painting<0.55
     plt.imshow(binarized);
    

4.Declaring Kernel

    square = np.array([[1,1,1],
                      [1,1,1],
                      [1,1,1]])
  1. Dilation function

     def multi_dil(im, num, element=square):
     for i in range(num):
         im = dilation(im, element)
         return im
    
  2. Erosion function

    def multi_ero(im, num, element=square):
    for i in range(num):
        im = erosion(im, element)
        return im
    
  3. Functions Applied

    plt.figure(figsize=(6,6))
    multi_dilated = multi_dil(binarized, 7)
    area_closed = area_closing(multi_dilated, 50000)
    multi_eroded = multi_ero(area_closed, 7)
    opened = opening(multi_eroded)
    plt.imshow(opened);
    
  4. Label function

    plt.figure(figsize=(6,6))
    label_im = label(opened)
    regions = regionprops(label_im)
    plt.imshow(label_im); 
    
  5. Extract features

    properties = ['area','convex_area','bbox_area', 'extent', 'mean_intensity','solidity', 'eccentricity', 'orientation']
    pd.DataFrame(regionprops_table(label_im, gray_painting, 
    properties=properties))
    
  6. Filtering Regions

    masks = []
    bbox = []
    list_of_index = []
    for num, x in enumerate(regions):
        area = x.area
        convex_area = x.convex_area
        if (num!=0 and (area>100) and (convex_area/area <1.05)
        and (convex_area/area >0.95)):
        masks.append(regions[num].convex_image)
        bbox.append(regions[num].bbox)   
        list_of_index.append(num)
     count = len(masks)
    
  7. Extracting Images

     fig, ax = plt.subplots(2, int(count/2), figsize=(15,8))
     for axis, box, mask in zip(ax.flatten(), bbox, masks):
         red  =  painting[:,:,0][box[0]:box[2], box[1]:box[3]] * mask
         green = painting[:,:,1][box[0]:box[2], box[1]:box[3]] * mask
         blue  = painting[:,:,2][box[0]:box[2], box[1]:box[3]] * mask
         image = np.dstack([red,green,blue])
         axis.imshow(image)
     plt.tight_layout()
    
     plt.figure(figsize=(6,6))
    
     rgb_mask = np.zeros_like(label_im)
     for x in list_of_index:
         rgb_mask += (label_im==x+1).astype(int)
         red  =  painting[:,:,0] * rgb_mask
         green = painting[:,:,1] * rgb_mask
         blue  = painting[:,:,2] * rgb_mask
         image = np.dstack([red,green,blue])
     plt.imshow(image);
    

I am getting an error.

ValueError: Number of columns must be a positive integer, not 0

Akash Chakraborty
  • 57
  • 1
  • 2
  • 13
  • *if anyone can complete this task that will be very helpful for me* - I bet it would – Adelin Jul 05 '18 at 12:20
  • If there's a specific part you're struggling with we can help, but no one's going to do your homework for you. – dashiell Jul 05 '18 at 12:21
  • Img=cv2.imread("C://Users//USER//Pictures//Saved Pictures//fig2.tif",0) [M,N]=Img.shape[:2] Connected=np.zeros((M,N)) Offsets=[-1,M,1,-M] Index=[] – Akash Chakraborty Jul 05 '18 at 12:24
  • for i in range(M): for j in range(N): if(Img(i,j)==1): No_of_Objects=N0_of_Objects+1 Index=[((j-1)*M + i)] Connected(Index)=Mark while(Index!=0): Img(Index)=0 Neighbors=bsxfun(@plus,Index,Offsets) Neighbors = unique(Neighbors(:)) Index = Neighbors(find(Image(Neighbors))) Connected(Index)=Mark Mark=Mark+Difference – Akash Chakraborty Jul 05 '18 at 12:24
  • What can I use instead of@plus in python? – Akash Chakraborty Jul 05 '18 at 12:25

1 Answers1

1

There is a possible approach which is not very far from what you attempted. Assume the background pixels are assigned the label 0, and the object pixels the value 1.

  • scan the image row by row;

  • when you meet a pixel 1, set a new label and perform a flood fill operation, replacing 1 by the new label.

Flood filling can be implemented very simply:

  • set the starting pixel to the new label;

  • recursively fill the eight neighbors, if they have a 1.

https://en.wikipedia.org/wiki/Flood_fill

The code of this version is pretty simple. But you will notice that it can easily overflow the stack because the number of pending fills can be as large as the image size.

def FloodFill(X, Y, Label):
    I[X,Y]= Label
    for all 8-way neighbors (X'=X±1, Y'=Y±1, inside image):
        if I[X',Y'] == 1:
            FloodFill(X', Y', Label)

def CCL(Image I):
    Label= 1
    for Y in range(I.Height):
        for X in range(I.Width):
            if I[X, Y] == 1:
                Label+= 1
                FloodFill(X, Y, Label)

So I would recommend the scanline version, which is a little more involved.

https://en.wikipedia.org/wiki/Flood_fill#Scanline_fill