def _region_features_for(histone, dna, region):
    pixels0 = histone[region].ravel()
    pixels1 = dna[region].ravel()
    bin0 = pixels0 > histone.mean()
    bin1 = pixels1 > dna.mean()
    overlap = [np.corrcoef(pixels0, pixels1)[0, 1], (bin0 & bin1).mean(), (bin0 | bin1).mean()]

    spi = mh.sobel(histone, just_filter=1)
    sp = spi[mh.erode(region)]
    sdi = mh.sobel(dna, just_filter=1)
    sd = sdi[mh.erode(region)]
    sobels = [
        np.dot(sp, sp) / len(sp),
        np.abs(sp).mean(),
        np.dot(sd, sd) / len(sd),
        np.abs(sd).mean(),
        np.corrcoef(sp, sd)[0, 1],
        np.corrcoef(sp, sd)[0, 1] ** 2,
        sp.std(),
        sd.std(),
    ]

    return np.concatenate(
        [
            [region.sum()],
            haralick(histone * region, ignore_zeros=True).mean(0),
            haralick(dna * region, ignore_zeros=True).mean(0),
            overlap,
            sobels,
            haralick(mh.stretch(sdi * region), ignore_zeros=True).mean(0),
            haralick(mh.stretch(spi * region), ignore_zeros=True).mean(0),
        ]
    )
Ejemplo n.º 2
0
def _region_features_for(histone, dna, region):
    pixels0 = histone[region].ravel()
    pixels1 = dna[region].ravel()
    bin0 = pixels0 > histone.mean()
    bin1 = pixels1 > dna.mean()
    overlap = [
        np.corrcoef(pixels0, pixels1)[0, 1],
        (bin0 & bin1).mean(),
        (bin0 | bin1).mean(),
    ]

    spi = mh.sobel(histone, just_filter=1)
    sp = spi[mh.erode(region)]
    sdi = mh.sobel(dna, just_filter=1)
    sd = sdi[mh.erode(region)]
    sobels = [
        np.dot(sp, sp) / len(sp),
        np.abs(sp).mean(),
        np.dot(sd, sd) / len(sd),
        np.abs(sd).mean(),
        np.corrcoef(sp, sd)[0, 1],
        np.corrcoef(sp, sd)[0, 1]**2,
        sp.std(),
        sd.std(),
    ]

    return np.concatenate([
        [region.sum()],
        haralick(histone * region, ignore_zeros=True).mean(0),
        haralick(dna * region, ignore_zeros=True).mean(0),
        overlap,
        sobels,
        haralick(mh.stretch(sdi * region), ignore_zeros=True).mean(0),
        haralick(mh.stretch(spi * region), ignore_zeros=True).mean(0),
    ])
Ejemplo n.º 3
0
    def _start(self, component, channel, prop, image):
        if not self.has_glcm and not self.has_hrlk:
            return
        assert image.ndim == 2, 'Expecting 2D object image, got shape {}'.format(
            image.shape)
        # Mask out parts of object image that don't overlap with object binary image (i.e. set to 0)
        image = image * prop.image.astype(image.dtype)
        if exposure.is_low_contrast(image, fraction_threshold=.01):
            image = np.zeros(image.shape, dtype=np.uint8)
        else:
            # Both greycomatrix and haralick require 8-bit images
            image = exposure.rescale_intensity(image,
                                               in_range='dtype',
                                               out_range='uint8').astype(
                                                   np.uint8)
        assert image.dtype == np.uint8

        # NOTE: Both skimage and mahotas GLCM-based features are very similar though there is a critical difference
        # in that the mahotas implementation allows zeros to be ignored, which leads to substantially different
        # results that are otherwise nearly identical.  Also, the mahotas version is used in CellProfiler
        # with ignore_zeros=True so it should be preferred.
        # TODO: make distance parameterized
        distance = 16

        # Initialize GLCM matrix if necessary
        if self.has_glcm:
            from skimage.feature import greycomatrix, greycoprops
            # With these 4 angles, results are nearly identical to mhf.haralick with ignore_zeros=False
            glcm = greycomatrix(image, [distance],
                                [0, np.pi / 2, np.pi, 3 * np.pi / 2],
                                symmetric=True,
                                normed=True)
            # Average across array of shape [d, a] where d = num distances (1 in this case)
            # and a = num angles (4 in this case)
            self.glcm_fn = lambda feature: (greycoprops(glcm, feature).mean(),
                                            prop.label)

        # Gather Haralick features if necessary
        if self.has_hrlk:
            from mahotas import features as mhf
            try:
                hrlk = mhf.haralick(image,
                                    distance=distance,
                                    ignore_zeros=True,
                                    return_mean=True)
            except ValueError as e:
                # If an error is thrown about empty features (which can happen even with non-empty images),
                # then get the default values using a small empty array
                if 'mahotas.haralick_features: the input is empty. Cannot compute features!' not in str(
                        e):
                    raise
                hrlk = mhf.haralick(np.zeros((2, 2), dtype=np.uint8),
                                    distance=1,
                                    ignore_zeros=False,
                                    return_mean=True)
            hrlk = dict(zip(TEXTURE_HRLK_FEATURES, hrlk))
            self.hrlk_fn = lambda feature: (hrlk[feature], prop.label)
Ejemplo n.º 4
0
def extract_features(image):
    hsv_image, ycrcb_image = cv2.cvtColor(image,
                                          cv2.COLOR_BGR2HSV), cv2.cvtColor(
                                              image, cv2.COLOR_BGR2YCrCb)
    channels = cv2.split(hsv_image) + cv2.split(ycrcb_image)
    lbp_features = [
        local_binary_pattern(ch, 18, 2, method='uniform') for ch in channels
    ]
    hist_lbp_features = [
        np.histogram(lf, bins=19, density=True)[0] for lf in lbp_features
    ]
    haralick_features = np.append(
        haralick(hsv_image).mean(axis=0),
        haralick(ycrcb_image).mean(axis=0))
    return np.append(hist_lbp_features, haralick_features)
Ejemplo n.º 5
0
def glcm_16_and_6(patch):
    """
    features_glcm_16 is a 16D vector with
        the features Energy, Local Homogeneity, Entropy and Correlation 
        for each one of the angles 0, 45, 90 and 135 .
    
    features_glcm_6 is a 6D vector with the mean values for the angles above and the
        features Energy, Local Homogeneity, Entropy, 
        Inertia, Cluster Shade and Cluster Prominence.
    """

    all_haralick = features.haralick(
        patch)  # All 13 (see method for about 14th feature)
    other_feats = _glcm_6_other_attrs(
        patch)  # Inertia, Cluster Shade and Prominence

    # Instead of a 4x4 matrix, here we go for a 16 dimensional vector.
    features_glcm_16 = np.concatenate([
        all_haralick[:, 0], all_haralick[:, 4], all_haralick[:, 8],
        all_haralick[:, 2]
    ])

    features_glcm_6 = np.mean([
        all_haralick[:, 0], all_haralick[:, 4], all_haralick[:, 8],
        other_feats[0], other_feats[1], other_feats[2]
    ],
                              axis=1)

    return [features_glcm_16, features_glcm_6]
Ejemplo n.º 6
0
def get_Haralick(im_arr, dist=1, grid_size=1, j=10):
    """
    Haralick para una imagen.
    :param im_arr:
    :param dist:
    :param grid_size:
    :return: 13*4*grid_size^2 array length
    """

    # if j % 30 == 0:
    #     print("|", end = "", flush = True)
    img = np.asarray(im_arr).astype(int)
    img = mahotas.stretch(img, 31)
    window_size = (np.asarray([img.shape]) / grid_size).astype(int)[0]
    im_grid = np.asarray(skimage.util.view_as_blocks(img, tuple(window_size)))
    windows = []
    for i in range(grid_size):
        for j in range(grid_size):
            windows.append(im_grid[i, j])
    haralick_features = []
    for i in range(len(windows)):
        try:
            h = haralick(windows[i], distance=dist)
        except ValueError:
            raise
            print('error in Haralick!')
            print(windows[i].shape)
            print(windows[i])
            quit()
        h = np.ravel(np.asarray(h))
        haralick_features.append(h)
    out = np.ravel(np.asarray(haralick_features))
    return out
def make_hara_map(im, rects):
    # draws heatmap of haralick texture PCA dim1 variance
    if len(rects)==0:
        return None
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    hara = []
    for r in rects:
        # slice images as: img[y0:y1, x0:x1]
        hara.append(pcaFG.transform(haralick(im[r[0][1]:r[1][1], r[0][0]:r[1][0]]).mean(0).reshape(1, -1)))
    
    hara = np.array(hara)
    haraMean = np.mean(hara, axis=0)
    haraStd = np.std(hara, axis=0)
    haraMins = np.min(hara, axis=0)
    haraMaxs = np.max(hara, axis=0)
    norm = (haraMaxs-haraMins)
    copy = im.copy()
    copy = cv2.cvtColor(copy, cv2.COLOR_BGRA2RGBA)
    im = cv2.cvtColor(im, cv2.COLOR_BGRA2RGBA)
    
    for i in range(hara.shape[0]):
        brightScale = 255*(hara[i] - haraMins)/norm
        bright = brightScale[0][0]
        r = rects[i]
        cv2.rectangle(copy, r[0], r[1], [0, bright, 0, 255], -1)
    
    f, axarr = plt.subplots(2, 1)
    axarr[0].imshow(copy)
    axarr[1].imshow(im)
    plt.show()
Ejemplo n.º 8
0
def get_texture_feats(row, img):
    feats = mah.haralick(img, distance=2)
    contrast = feats[:, 1].mean()
    var = feats[:, 3].mean()
    idm = feats[:, 4].mean()

    row += [contrast, var, idm]

    return row
Ejemplo n.º 9
0
    def extract_features(image):
        """this method applies the hu moments and the haralick method on a given image

        Arguments:
            image {ndarray} -- the image whose the features will be extracted

        Returns:
            numpy.array -- an array with the extracted features
        """
        return np.r_[moments_hu(image), haralick(image).flatten()]
Ejemplo n.º 10
0
def ubyte_haralick(image,**kwargs):
	with catch_warnings():
		simplefilter("ignore",category=UserWarning)
		ubyte_image = img_as_ubyte(image)
	try:
		features = haralick(ubyte_image,**kwargs)
	except ValueError:
		features = [np.nan]*13

	return features
Ejemplo n.º 11
0
 def get_haralick(self):
     """
         Returns a vector of Haralick features for the image.
     """
     if (self.obj, self.illumination,
             self.flipping) not in CACHES["haralick"]:
         image = (self.get_image() * 255).astype("uint8")
         CACHES["haralick"][(self.obj, self.illumination,
                             self.flipping)] = haralick(image)
     return CACHES["haralick"][(self.obj, self.illumination, self.flipping)]
Ejemplo n.º 12
0
def get_avg_hara(im, rects):
    # returns the haralick texture averaged over all rectangles in an image
    if len(rects) == 0:
        return None
    im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    hara = 0
    for r in rects:
        # slice images as: img[y0:y1, x0:x1]
        hara += haralick(im[r[0][1]:r[1][1], r[0][0]:r[1][0]]).mean(0)
    hara /= (len(rects))
    return hara
def get_features(im):
    # gets haralick and color histogram PCA of image
    h, w = im.shape[:2]
    if w > 450:
        im = imutils.resize(im, width=450)
        h, w = im.shape[:2]
    im = im[h/5:-h/5, w/5:-w/5] # only use center 60% of image to avoid background noise
    gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    hara = haralick(gray).flatten()
    cHist = get_color_hists(im)
    return np.hstack((hara, cHist.T[:,0]))
def H_Tex(image, eps=1e-7):
    m_haralick = haralick(image)
    assert m_haralick.shape == (4, 13)
    # normalize wrt each row
    row_sum = m_haralick.sum(axis=1)
    m_haralick = m_haralick / (row_sum[:, np.newaxis] + eps)

    assert (m_haralick.shape == (
        4,
        13)), "haralick shape expected (4,13), got {}".format(m_haralick.shape)
    return m_haralick.ravel()
def get_avg_hara(im, rects):
    # returns the haralick texture averaged over all rectangles in an image
    if len(rects)==0:
        return None
    im = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
    hara = 0
    for r in rects:
        # slice images as: img[y0:y1, x0:x1]
        hara += haralick(im[r[0][1]:r[1][1], r[0][0]:r[1][0]]).mean(0)
    hara /= (len(rects))
    return hara
Ejemplo n.º 16
0
def analize_and_threshold(images,selected_feature):
	features = []
	for img in images:
		features.append(haralick(img).mean(axis=0)[selected_feature])
	thresh_value = statistics.mean(features)
	indexes = []
	i=0
	for d in features:
		if(d>thresh_value):
			indexes.append(i)
		i+=1
	return indexes
Ejemplo n.º 17
0
    def calculate(self, resource):
        #initalizing
        except_image_only(resource)

        image_uri = resource.image
        #image_uri = BQServer().prepare_url(image_uri, remap='gray')
        im = image2numpy(image_uri, remap='gray')
        im = np.uint8(im)
        #calculate descriptor
        descritptors = np.hstack(haralick(im))

        #initalizing rows for the table
        return descritptors
Ejemplo n.º 18
0
def calcFeatures(img):
    # Remove the 14th (last) feature name since it is not calculated by default
    featureLabels = haralick_labels[:-1]
    # Return only mean value of each features for all 4 directions
    rawFeatures = haralick(img)

    featureDict = {}
    for i, angle in enumerate(angleList):
        featureDict[angle] = {}

        for j, featureName in enumerate(featureLabels):
            featureDict[angle][featureName] = rawFeatures[i][j]

    featureDict['Avg'] = {}
    featureMean = rawFeatures.mean(axis=0)
    for j, featureName in enumerate(featureLabels):
        featureDict['Avg'][featureName] = featureMean[j]

    return featureDict
 def haralick_all_features(X, distance=1):
     f = []
     for i in range(len(X)):
         I = cv2.imread(X[i])
         if I is None or I.size == 0 or np.sum(
                 I[:]) == 0 or I.shape[0] == 0 or I.shape[1] == 0:
             h = np.zeros((1, 13))
         else:
             I = cv2.cvtColor(I, cv2.COLOR_BGR2GRAY)
             h = haralick(I,
                          distance=distance,
                          return_mean=True,
                          ignore_zeros=False)
             h = np.expand_dims(h, 0)
         if i == 0:
             f = h
         else:
             f = np.vstack((f, h))
     return f
Ejemplo n.º 20
0
def Haralick_Textures(img, window_x, window_y, distance = 1):
    """Returns an un-normalized 13 channel haralick texture image. Input image needs to be 
    grey-scaled and of type uint. Window Dimensions need to be odd. Requires mahotas module."""
    out = np.zeros((img.size, 13), dtype = np.double)
    
    img_tmp = np.lib.pad(img, [window_y//2,window_x//2], "symmetric")
    
    window_shape = (window_x, window_y)
    
    windowed_array = view_as_windows(img_tmp, window_shape)
    
    windowed_array_flat = np.reshape(windowed_array, (img.size, window_shape[0], window_shape[1]))
        
    for i, window in enumerate(windowed_array_flat):
        haralick_features = haralick(f = window, return_mean = True, distance = distance)
        out[i] = haralick_features
    
    out = np.reshape(out, (img.shape[0], img.shape[1], 13))
    
    return out
Ejemplo n.º 21
0
def HaralickProcessing(patch_in):
    """Function to compute Haralick for a patch

    Parameters
    ----------
    patch_in: ndarray of int
        2D or 3D array containing the image information

    Returns
    -------
    hara_fea: ndarray of np.double
        A 4x13 or 4x14 feature vector (one row per direction) if `f` is 2D,
        13x13 or 13x14 if it is 3D. The exact number of features depends on the
        value of ``compute_14th_feature`` Also, if either ``return_mean`` or
        ``return_mean_ptp`` is set, then a single dimensional array is
        returned.
    """

    # Compute Haralick feature
    return haralick(patch_in)
Ejemplo n.º 22
0
def get_haralick_features(image,
                          ignore_zeros=False,
                          get_14th_feature=False,
                          distance=1):
    """
	Function to return Haralick features for given cooccurrence matrices
	:param image: OpenCV image ndaaray of dtype int64
	:param ignore_zeros: boolean, optional (Default: False)
		Can be used to have the function ignore any zero-valued pixels (as background).
		If there are no-nonzero neighbour pairs in all directions, an exception is raised.
	:param get_14th_feature: boolean, optional (Default: False)
	:param distance: int, optional (Default: 1)
		Distance between pixel pairs
	:return: ndarray of np.double
		A 4x13 or 4x14 feature vector (one row per direction) if `f` is 2D, 13x13 or 13x14 if it is 3D.
		The exact number of features depends on the value of "compute_14th_feature"
	"""

    return mfeats.haralick(image,
                           ignore_zeros=ignore_zeros,
                           compute_14th_feature=get_14th_feature,
                           distance=distance)
Ejemplo n.º 23
0
def get_Haralick(im_arr, dist=1, grid_size=1):
    """
    Haralick para una imagen.
    :param im_arr:
    :param dist:
    :param grid_size:
    :return: 13*4*grid_size^2 array length
    """
    img = np.asarray(im_arr).astype(int)
    img = mahotas.stretch(img, 31)
    window_size = (np.asarray([img.shape]) / grid_size).astype(int)[0]
    im_grid = np.asarray(skimage.util.view_as_blocks(img, tuple(window_size)))
    windows = []
    for i in range(grid_size):
        for j in range(grid_size):
            windows.append(im_grid[i, j])
    haralick_features = []
    for i in range(len(windows)):
        h = haralick(windows[i], distance=dist)
        h = np.ravel(np.asarray(h))
        haralick_features.append(h)
    out = np.ravel(np.asarray(haralick_features))
    return out
Ejemplo n.º 24
0
def haralick_features(names, distance=1):
    """
    :param names: list of full file names of the images
    :param distance: distance parameter (set to default as 1)
    :return: f (M x 13) matrix where M is the number of image files in name
    """
    f = []
    for i in range(len(names)):
        I = cv2.imread(names[i])
        if I is None or I.size == 0 or np.sum(
                I[:]) == 0 or I.shape[0] == 0 or I.shape[1] == 0:
            h = np.zeros((1, 13))
        else:
            I = cv2.cvtColor(I, cv2.COLOR_BGR2GRAY)
            h = haralick(I,
                         distance=distance,
                         return_mean=True,
                         ignore_zeros=False)
            h = np.expand_dims(h, 0)
        if i == 0:
            f = h
        else:
            f = np.vstack((f, h))
    return f
Ejemplo n.º 25
0
 def haralick_all_features(self, names, idx, distance=1):
     # if os.path.exists(self.data_location + 'features/' + self.type1 + '/haralick_' + self.data_name + '.npz'):
     # 	f = np.load(open(self.data_location + 'features/' + self.type1 + '/haralick_' + self.data_name + '.npz', 'rb'))
     # 	return f.f.arr_0[idx, :]
     # else:
     f = []
     for i in range(len(names)):
         I = cv2.imread(names[i])
         if I is None or I.size == 0 or np.sum(
                 I[:]) == 0 or I.shape[0] == 0 or I.shape[1] == 0:
             h = np.zeros((1, 13))
         else:
             I = cv2.cvtColor(I, cv2.COLOR_BGR2GRAY)
             h = haralick(I,
                          distance=distance,
                          return_mean=True,
                          ignore_zeros=False)
             h = np.expand_dims(h, 0)
         if i == 0:
             f = h
         else:
             f = np.vstack((f, h))
     # np.savez(open(self.data_location + 'features/' + self.type1 + '/haralick_' + self.data_name + '.npz', 'wb'), f)
     return f[idx, :]
Ejemplo n.º 26
0
def diseaseFeatureExtraction(filename):
    selem = disk(8)

    #THRESHOLDING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    image = data.imread(filename)
    image = checkPythonImage(image)

    hsv2 = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

    grayimage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    grayimage = checkPythonGrayImage(grayimage)

    thresh = threshold_otsu(grayimage)

    elevation_map = sobel(grayimage)

    markers = np.zeros_like(grayimage)

    if ((grayimage < thresh).sum() > (grayimage > thresh).sum()):
        markers[grayimage < thresh] = 1
        markers[grayimage > thresh] = 2
    else:
        markers[grayimage < thresh] = 2
        markers[grayimage > thresh] = 1

    segmentation = morphology.watershed(elevation_map, markers)

    segmentation = dilation(segmentation - 1, selem)
    segmentation = ndimage.binary_fill_holes(segmentation)

    segmentation = np.logical_not(segmentation)
    grayimage[segmentation] = 0

    watershed_mask = np.empty_like(grayimage, np.uint8)
    width = 0
    height = 0
    while width < len(watershed_mask):

        while height < len(watershed_mask[width]):

            if grayimage[width][height] == 0:
                watershed_mask[width][height] = 0
            else:
                watershed_mask[width][height] = 1

            height += 1
            pass

        width += 1
        height = 0
        pass

    #SPLITTING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    image = cv2.bitwise_and(image, image, mask=watershed_mask)
    hsv = ''
    if image.shape[2] == 3:
        hsv = color.rgb2hsv(image)
    elif image.shape[2] == 4:
        image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
        hsv = color.rgb2hsv(image)
    h, s, v = cv2.split(hsv2)

    #MASKING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
    mask = cv2.inRange(h, 40, 80)
    cv2.bitwise_not(mask, mask)

    res = cv2.bitwise_and(image, image, mask=mask)
    res_gray = cv2.bitwise_and(grayimage, grayimage, mask=mask)

    harfeatures = haralick(res.astype(int),
                           ignore_zeros=True,
                           return_mean=True)

    #glcm = greycomatrix(res_gray, [5], [0], 256)
    #contrast = greycoprops(glcm, 'contrast')[0, 0]
    #ASM = greycoprops(glcm, 'ASM')[0, 0]
    #dissimilarity = greycoprops(glcm, 'dissimilarity')[0, 0]
    #homogeneity = greycoprops(glcm, 'homogeneity')[0, 0]
    #energy = greycoprops(glcm, 'energy')[0, 0]

    features = []

    #features.append(contrast)
    #features.append(ASM)
    #features.append(dissimilarity)
    #features.append(homogeneity)
    #features.append(energy)

    hist = cv2.calcHist([res], [0], None, [256], [0, 256])
    w, h, c = res.shape
    numPixel = w * h

    num = 0
    for index in hist:

        if num != 0 and num < 255:
            features.append(index[0] / (numPixel - hist[0][0]))

        num = num + 1

        pass

    for harfeature in harfeatures:
        features.append(harfeature)
        pass

    output = np.empty((1, len(features)), 'float')

    a = np.array(list(features))
    output[0, :] = a[:]
    return output
Ejemplo n.º 27
0
        edges = n.hypot(sx, sy)
                
        lines = probabilistic_hough(edges, threshold=10, line_length=80, line_gap=3)
        #plt.figure(figsize=(10, 10))
        #plt.imshow(edges * 0)
        #plot.clear()
        #plot.axis('off')
        #for line in lines:
        #    p0, p1 = line
        #    plot.plot((p0[0], p1[0]), (p0[1], p1[1]))
        #fig.savefig('pinturas/%s/hough.%s.png' % (path, i))
        #print area, peri, raz, len(lines)
        ql = len(lines)

        # calculando agora os haralick
        h = mf.haralick(n.array(im_media))

        m = [#pearsons.mean(), # media pearson
             #pearsons.std(), # std pearson
            # CINZA
            imtools.entropy(im), # entropia
            en_li.mean(), # media energias das linhas
            en_li.std(), # std energias das linhas
            en_co.mean(), # media energias das colunas
            en_co.std(), # std energias das colunas
            # centroide linha
            n.sum([en_li[j]*j for j in range(len(en_li))]) / n.sum(en_li),
            # centroide coluna
            n.sum([en_co[j]*j for j in range(len(en_co))]) / n.sum(en_co),
            # media energias total
            energias.mean(),
Ejemplo n.º 28
0
def get_blob_element(mask, rect, skel, num_blob_pixels, color, color_variance, grey, depth, label, is_subblob = False):
    # Scale image for scale-invariant shape features
    # Make it so the longest edge is equal to SHAPE_FEATURE_SIZE
    resized_image = mahotas.imresize(mask,
                                     float(SHAPE_FEATURE_SIZE) / max(mask.shape))

    z_moments = zernike_moments(resized_image, SHAPE_FEATURE_SIZE, degree = Z_ORDER)

    blob_element = xml.Element(label)
    
    x_1 = rect[0]
    y_1 = rect[1]
    x_2 = x_1 + rect[2]
    y_2 = y_1 + rect[3]

    blob_element.attrib['x'] = str(rect[0])
    blob_element.attrib['y'] = str(rect[1])
    blob_element.attrib['width'] = str(rect[2])
    blob_element.attrib['height'] = str(rect[3])
    rect_center = (rect[0] + .5 * rect[2],
                   rect[1] + .5 * rect[3])
    if (skel is not None and len(skel) > 0 ):
        blob_element.attrib['head_dist'] = str(distance(rect_center,
                                                skel['HEAD']['2d']))
        blob_element.attrib['right_hand_dist'] = str(distance(rect_center,
                                                skel['RIGHT_HAND']['2d']))
        blob_element.attrib['left_hand_dist'] = str(distance(rect_center,
                                                skel['LEFT_HAND']['2d']))
    
    

    
    features_element = xml.Element('features')
    blob_element.append(features_element)

    size_element = xml.SubElement(features_element, 'size')
    xml.SubElement(size_element, 'pixels').text = str(num_blob_pixels)

    hu_element = get_hu_moments_element(mask)

    features_element.append(hu_element)

    grey_masked_image = grey & mask

    blob_depth = depth & mask

    if is_subblob:
        blob_depth_rect = blob_depth
        blob_mask_rect = mask
    else:
        blob_depth_rect = blob_depth[y_1:y_2, x_1:x_2]
        blob_mask_rect = mask[y_1:y_2, x_1:x_2]


    normal_vector_histogram = get_normal_vector_histogram(blob_depth_rect, blob_mask_rect.astype(numpy.uint8))
    
    #print normal_vector_histogram

    if normal_vector_histogram is None:
        print 'Error calculating normal_vector_histogram'
        return None

    normal_histogram_element = xml.Element('normalhistogram')

    for i in xrange(normal_vector_histogram.size):
        xml.SubElement(normal_histogram_element, 'a_' + str(i)).text = str(normal_vector_histogram[i])

    features_element.append(normal_histogram_element)

    haralick_element = xml.Element('haralick')

    haralick_features = haralick(grey_masked_image)
    # Average the rows (the different directions of the features)
    haralick_features_averaged = numpy.mean(haralick_features,axis=0)
    #print len(haralick_features_averaged)

    for i in xrange(NUM_HARALICK_FEATURES):
        xml.SubElement(haralick_element, 'a_' + str(i)).text = str(haralick_features_averaged[i])

    features_element.append(haralick_element)

    zernike_element = xml.Element('zernike')
        
    for i in xrange(Z_FEATURES):
        xml.SubElement(zernike_element, 'a_' + str(i)).text = str(z_moments[i])

    features_element.append(zernike_element)
    
    rgb_element = xml.Element('rgb')
    xml.SubElement(rgb_element, 'r').text = str(color[0])
    xml.SubElement(rgb_element, 'g').text = str(color[1])
    xml.SubElement(rgb_element, 'b').text = str(color[2])

    features_element.append(rgb_element)
    
    rgb_variance_element = xml.Element('rgb_var')
    xml.SubElement(rgb_variance_element, 'r').text = str(color_variance[0])
    xml.SubElement(rgb_variance_element, 'g').text = str(color_variance[1])
    xml.SubElement(rgb_variance_element, 'b').text = str(color_variance[2])
    
    features_element.append(rgb_variance_element)

    return blob_element
Ejemplo n.º 29
0
def diseaseFeatureExtraction(filename):
	selem = disk(8)

	#THRESHOLDING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFF
	image = data.imread(filename)
	image = checkPythonImage(image)

	hsv2 = cv2.cvtColor(image, cv2.COLOR_BGR2HSV)

	grayimage = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
	grayimage = checkPythonGrayImage(grayimage)

	thresh = threshold_otsu(grayimage)

	elevation_map = sobel(grayimage)

	markers = np.zeros_like(grayimage)

	if ((grayimage<thresh).sum() > (grayimage>thresh).sum()):
		markers[grayimage < thresh] = 1
		markers[grayimage > thresh] = 2
	else:
		markers[grayimage < thresh] = 2
		markers[grayimage > thresh] = 1


	segmentation = morphology.watershed(elevation_map, markers)

	segmentation = dilation(segmentation-1, selem)
	segmentation = ndimage.binary_fill_holes(segmentation)

	segmentation = np.logical_not(segmentation)
	grayimage[segmentation]=0;

	watershed_mask = np.empty_like(grayimage, np.uint8)
	width = 0
	height = 0
	while width < len(watershed_mask):

		while height < len(watershed_mask[width]):

			if grayimage[width][height] == 0:
				watershed_mask[width][height] = 0
			else:
				watershed_mask[width][height] = 1

			height += 1
			pass

		width += 1
		height = 0
		pass



	#SPLITTING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
	image = cv2.bitwise_and(image,image,mask = watershed_mask)
	hsv = ''
	if image.shape[2] == 3:
		hsv = color.rgb2hsv(image)
	elif image.shape[2] == 4:
		image = cv2.cvtColor(image, cv2.COLOR_BGRA2BGR)
		hsv = color.rgb2hsv(image)
	h,s,v = cv2.split(hsv2)

	#MASKING STUFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF
	mask = cv2.inRange(h, 40, 80)
	cv2.bitwise_not(mask, mask)

	res = cv2.bitwise_and(image,image, mask= mask)
	res_gray = cv2.bitwise_and(grayimage,grayimage, mask=mask)
	
	harfeatures = haralick(res.astype(int), ignore_zeros=True, return_mean=True)

	#glcm = greycomatrix(res_gray, [5], [0], 256)
	#contrast = greycoprops(glcm, 'contrast')[0, 0]
	#ASM = greycoprops(glcm, 'ASM')[0, 0]
	#dissimilarity = greycoprops(glcm, 'dissimilarity')[0, 0]
	#homogeneity = greycoprops(glcm, 'homogeneity')[0, 0]
	#energy = greycoprops(glcm, 'energy')[0, 0]
	
	features = []
	
	#features.append(contrast)
	#features.append(ASM) 
	#features.append(dissimilarity)
	#features.append(homogeneity)
	#features.append(energy)

	hist = cv2.calcHist([res],[0],None,[256],[0,256])
	w, h, c = res.shape
	numPixel = w * h

	num = 0
	for index in hist:

		if num != 0 and num<255:
			features.append(index[0]/(numPixel-hist[0][0]))

		num = num + 1

		pass

	for harfeature in harfeatures:
		features.append(harfeature)
		pass	

	output = np.empty( (1, len(features)), 'float' )
	
	a = np.array(list(features))
	output[0,:]=a[:]
	return output
nu = moments_normalized(mu)
hu = moments_hu(nu)

features.extend(hu)


# Texture - Haralick Texture
# conda install -c conda-forge mahotas
from mahotas.features import haralick
from skimage.color import rgb2gray
from skimage.util import img_as_ubyte

grayscale = rgb2gray(img)
grayscale = img_as_ubyte(grayscale)

haralick_features = haralick(grayscale)
haralick_features = haralick_features.flatten()

features.extend(haralick_features)

# Texture - Local Binary Patterns (LBP)
from skimage.feature import local_binary_pattern
from skimage.color import rgb2gray
from skimage.util import img_as_ubyte

grayscale = rgb2gray(img)
grayscale = img_as_ubyte(grayscale)

# settings for LBP
radius = 3
n_points = 8 * radius
Ejemplo n.º 31
0
def IdentifyMango(imgnp):
    Result = {}
    orignal = imgnp
    #orignal = cv2.resize(orignal,(4000,4000))
    img = orignal
    labformat = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, thresh = cv2.threshold(gray, gray.mean(), 255, cv2.THRESH_BINARY)
    thresh = 255 - thresh
    contours, heirachy = cv2.findContours(thresh, cv2.RETR_TREE,
                                          cv2.CHAIN_APPROX_SIMPLE)
    maxIndex = -1
    if len(contours) > 0:
        for i in range(len(contours)):
            if cv2.contourArea(contours[i]) >= cv2.contourArea(
                    contours[maxIndex]):
                maxIndex = i
                cv2.contourArea(contours[i])

    img_lab = labformat
    if maxIndex != -1:
        cv2.drawContours(img, contours, maxIndex, (255, 0, 0))
        MangoArea = cv2.contourArea(contours[maxIndex])
        x, y, w, h = cv2.boundingRect(contours[maxIndex])
        print("Detected Mango Area is : {}".format(MangoArea))

        orignal = orignal[y:y + h, x:x + w, :]
        red = orignal[:, :, 2].mean()
        green = orignal[:, :, 1].mean()
        blue = orignal[:, :, 0].mean()

    print("Shape of Lab Format", labformat.shape)
    a = img_lab[:, :, 1]
    b = img_lab[:, :, 2]
    shape = ShapeDetector(img)
    chaincode = shape.detectBoundary()

    channel_a_mean = a.mean()
    channel_b_mean = b.mean()
    print("Channel_A Mean : {}".format(channel_a_mean))
    print("Channel_B Mean : {}".format(channel_b_mean))
    print("Chain Code : {}".format(chaincode))
    Result['channela'] = channel_a_mean
    Result['channelb'] = channel_b_mean
    Result['chaincode'] = chaincode

    import pandas
    import numpy as np
    import matplotlib.pyplot as plt
    s3 = boto3.client('s3',
                      aws_access_key_id=AWS_ACCESS_KEY_ID,
                      aws_secret_access_key=AWS_SECRET_ACCESS_KEY)
    key = 'static/QualityFeatures.csv'
    if not os.path.exists(key):
        obj = s3.get_object(Bucket=AWS_STORAGE_BUCKET_NAME, Key=key)
        fp = open(key, 'wb')
        fp.write(obj['Body'].read())
        fp.close()
        del fp
    dataframe = pandas.read_csv(key)
    dataframe = dataframe.sort_values(by='Partially Ripe')
    ripe = dataframe.loc[dataframe['Partially Ripe'] == 'Ripe']
    unripe = dataframe.loc[dataframe['Partially Ripe'] == 'Unripe']
    partially_ripe = dataframe.loc[dataframe['Partially Ripe'] ==
                                   'Partially Ripe']
    ripe = ripe.iloc[:110, :].values
    unripe = unripe.iloc[:110, :].values
    partially_ripe = partially_ripe.iloc[:110, :].values

    data = []
    for i in range(ripe.shape[0]):
        data.append(ripe[i, :].tolist())
    for i in range(unripe.shape[0]):
        data.append(unripe[i, :].tolist())
    for i in range(partially_ripe.shape[0]):
        data.append(partially_ripe[i, :].tolist())

    data = np.asarray(data)

    Y = data[:, 0]
    X = data[:, 2:]
    from sklearn.preprocessing import LabelEncoder
    labelencoder = LabelEncoder()
    Y = labelencoder.fit_transform(Y)

    #Y[Y!=0] = 1
    #print(Y)

    from sklearn.model_selection import train_test_split

    X_train, X_test, y_train, y_test = train_test_split(X,
                                                        Y,
                                                        test_size=0.6,
                                                        random_state=1)

    from sklearn.preprocessing import StandardScaler, LabelEncoder

    sc = StandardScaler()
    X_train = sc.fit_transform(X_train)
    X_test = sc.transform(X_test)

    from sklearn.svm import SVC

    classifier = SVC(gamma='scale',
                     kernel='rbf',
                     decision_function_shape='ovo')
    #classifier = SVC(kernel='linear', random_state=0, decision_function_shape='ovo')
    classifier.fit(X_train, y_train)

    decision_tree = DecisionTreeClassifier()
    decision_tree.fit(X_train, y_train)

    perceptron_classifier = MLPClassifier()
    perceptron_classifier.fit(X_train, y_train)

    from sklearn.metrics import confusion_matrix

    y_pred = classifier.predict(X_test)
    svm_cm = confusion_matrix(y_test, y_pred)
    score = classifier.score(X_test, y_test)

    y_pred = decision_tree.predict(X_test)
    decision_tree_cm = confusion_matrix(y_test, y_pred)
    score2 = decision_tree.score(X_test, y_test)

    y_pred = perceptron_classifier.predict(X_test)
    perceptron_cm = confusion_matrix(y_test, y_pred)
    score3 = perceptron_classifier.score(X_test, y_test)
    print("Score of SVM For ripe and unripe : ", score)
    print("Score of Decision Tree For ripe and unripe : ", score2)
    print("Score of Percenptron Classifier for ripe and unripe : ", score3)
    Result['svm'] = score
    Result['des'] = score2
    Result['pes'] = score3
    from matplotlib.colors import ListedColormap

    # X_set, y_set = X_train, y_train
    # X1, X2 = np.meshgrid(np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.01),
    #                      np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.01))
    # plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
    #              alpha=0.75, cmap=ListedColormap(('red', 'green')))
    # plt.xlim(X1.min(), X1.max())
    # plt.ylim(X2.min(), X2.max())
    # for i, j in enumerate(np.unique(y_set)):
    #     plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
    #                 c=ListedColormap(('red', 'green'))(i), label=j)
    # plt.title('SVM (Training set)')
    # plt.xlabel('Age')
    # plt.ylabel('Estimated Salary')
    # plt.legend()
    # plt.show()
    #
    # # Visualising the Test set results
    # from matplotlib.colors import ListedColormap
    #
    # X_set, y_set = X_test, y_test
    # X1, X2 = np.meshgrid(np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.01),
    #                      np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.01))
    # plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
    #              alpha=0.75, cmap=ListedColormap(('red', 'green')))
    # plt.xlim(X1.min(), X1.max())
    # plt.ylim(X2.min(), X2.max())
    # for i, j in enumerate(np.unique(y_set)):
    #     plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
    #                 c=ListedColormap(('red', 'green'))(i), label=j)
    # plt.title('SVM (Test set)')
    # plt.xlabel('Age')
    # plt.ylabel('Estimated Salary')
    # plt.legend()
    # plt.show()

    features = [red, green, blue]
    features.extend(haralick(orignal).mean(0))
    features = np.asarray(features).reshape(1, -1)
    features = sc.transform(features)

    svm_val = classifier.predict(features)
    decision_tree_val = decision_tree.predict(features)
    preceptron_val = perceptron_classifier.predict(features)

    #print("SVM classfied Mango as : ",labelencoder.inverse_transform(svm_val))
    #print("Decision classfied Mango as : ",labelencoder.inverse_transform(decision_tree_val))
    #print("Perceptron classfied Mango as : ",labelencoder.inverse_transform(preceptron_val))
    Result['svmp'] = svm_val
    Result['desp'] = decision_tree_val
    Result['pesp'] = preceptron_val
    Result['svml'] = labelencoder.inverse_transform(svm_val)
    Result['desl'] = labelencoder.inverse_transform(decision_tree_val)
    Result['pesl'] = labelencoder.inverse_transform(preceptron_val)

    img = cv2.resize(img, (512, 512))
    Result['img'] = img

    key = 'static/QualityFeaturesMango.csv'
    if not os.path.exists(key):

        obj = s3.get_object(Bucket=AWS_STORAGE_BUCKET_NAME, Key=key)
        fp = open(key, 'wb')
        fp.write(obj['Body'].read())
        fp.close()
        del fp

    dataframe = pandas.read_csv(key)
    Y = dataframe.iloc[:, 0].values
    X = dataframe.iloc[:, 2:].values
    from sklearn.preprocessing import LabelEncoder
    labelencoder = LabelEncoder()
    Y = labelencoder.fit_transform(Y.reshape(-1, 1))

    # Y[Y!=0] = 1
    # print(Y)

    from sklearn.model_selection import train_test_split

    X_train, X_test, y_train, y_test = train_test_split(X,
                                                        Y,
                                                        test_size=0.6,
                                                        random_state=1)

    from sklearn.preprocessing import StandardScaler, LabelEncoder

    sc = StandardScaler()
    X_train = sc.fit_transform(X_train)
    X_test = sc.transform(X_test)

    from sklearn.svm import SVC

    classifier = SVC(gamma='scale',
                     kernel='rbf',
                     decision_function_shape='ovo')
    # classifier = SVC(kernel='linear', random_state=0, decision_function_shape='ovo')
    classifier.fit(X_train, y_train)

    decision_tree = DecisionTreeClassifier()
    decision_tree.fit(X_train, y_train)

    perceptron_classifier = MLPClassifier()
    perceptron_classifier.fit(X_train, y_train)

    from sklearn.metrics import confusion_matrix

    y_pred = classifier.predict(X_test)
    svm_cm = confusion_matrix(y_test, y_pred)
    score = classifier.score(X_test, y_test)

    y_pred = decision_tree.predict(X_test)
    decision_tree_cm = confusion_matrix(y_test, y_pred)
    score2 = decision_tree.score(X_test, y_test)

    y_pred = perceptron_classifier.predict(X_test)
    perceptron_cm = confusion_matrix(y_test, y_pred)
    score3 = perceptron_classifier.score(X_test, y_test)
    print("Score of SVM For ripe and unripe : ", score)
    print("Score of Decision Tree For ripe and unripe : ", score2)
    print("Score of Percenptron Classifier for ripe and unripe : ", score3)
    Result['tsvm'] = score
    Result['tdes'] = score2
    Result['tpes'] = score3
    from matplotlib.colors import ListedColormap

    # X_set, y_set = X_train, y_train
    # X1, X2 = np.meshgrid(np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.01),
    #                      np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.01))
    # plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
    #              alpha=0.75, cmap=ListedColormap(('red', 'green')))
    # plt.xlim(X1.min(), X1.max())
    # plt.ylim(X2.min(), X2.max())
    # for i, j in enumerate(np.unique(y_set)):
    #     plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
    #                 c=ListedColormap(('red', 'green'))(i), label=j)
    # plt.title('SVM (Training set)')
    # plt.xlabel('Age')
    # plt.ylabel('Estimated Salary')
    # plt.legend()
    # plt.show()
    #
    # # Visualising the Test set results
    # from matplotlib.colors import ListedColormap
    #
    # X_set, y_set = X_test, y_test
    # X1, X2 = np.meshgrid(np.arange(start=X_set[:, 0].min() - 1, stop=X_set[:, 0].max() + 1, step=0.01),
    #                      np.arange(start=X_set[:, 1].min() - 1, stop=X_set[:, 1].max() + 1, step=0.01))
    # plt.contourf(X1, X2, classifier.predict(np.array([X1.ravel(), X2.ravel()]).T).reshape(X1.shape),
    #              alpha=0.75, cmap=ListedColormap(('red', 'green')))
    # plt.xlim(X1.min(), X1.max())
    # plt.ylim(X2.min(), X2.max())
    # for i, j in enumerate(np.unique(y_set)):
    #     plt.scatter(X_set[y_set == j, 0], X_set[y_set == j, 1],
    #                 c=ListedColormap(('red', 'green'))(i), label=j)
    # plt.title('SVM (Test set)')
    # plt.xlabel('Age')
    # plt.ylabel('Estimated Salary')
    # plt.legend()
    # plt.show()

    features = [red, green, blue]
    features.extend(haralick(orignal).mean(0))
    features = np.asarray(features).reshape(1, -1)
    features = sc.transform(features)

    svm_val = classifier.predict(features)
    decision_tree_val = decision_tree.predict(features)
    preceptron_val = perceptron_classifier.predict(features)

    # print("SVM classfied Mango as : ",labelencoder.inverse_transform(svm_val))
    # print("Decision classfied Mango as : ",labelencoder.inverse_transform(decision_tree_val))
    # print("Perceptron classfied Mango as : ",labelencoder.inverse_transform(preceptron_val))
    Result['tsvmp'] = svm_val
    Result['tdesp'] = decision_tree_val
    Result['tpesp'] = preceptron_val
    Result['tsvml'] = labelencoder.inverse_transform(svm_val)
    Result['tdesl'] = labelencoder.inverse_transform(decision_tree_val)
    Result['tpesl'] = labelencoder.inverse_transform(preceptron_val)

    return Result
Ejemplo n.º 32
0
def haralick_GLCM_features(image):
    image = image.astype(int)
    features = haralick(image, return_mean=True)

    return features
Ejemplo n.º 33
0
#       correlation
#   result: 16-dimension vector, where [at1,at2,at3,at4] for each d
# GLCM 6:
#   d = 1, mean of the 4 directions, and with features
#       energy,
#       homogeneity,
#       entropy,
#       inertia,
#       cluster shade,
#       cluster prominence
#   result: 6-dimension vector like [mean_at1... mean_at6]

# TODO: use patches
actual_patch = patches_50[5][5]
# actual_patch = patches_70[5][5]
hfeats = features.haralick(actual_patch)
# TODO: is there any better way here?
feats_glcm_16 = list()
# http://www.ucalgary.ca/mhallbey/asm
# Should I get sqrt of hfetas[:,0]? Yes... actually won't.
# In other places we have -> Energy = ASM, hm...
feats_glcm_16.append(hfeats[:,
                            0])  # Energy = Homogeneity = Angular Second Moment
feats_glcm_16.append(
    hfeats[:, 4])  # Local Homogeneity (or Inverse Difference Moment)
feats_glcm_16.append(hfeats[:, 8])  # Entropy
feats_glcm_16.append(hfeats[:, 2])  # Correlation

feats_glcm_6 = list(np.mean([hfeats[:, 0], hfeats[:, 4], hfeats[:, 8]],
                            axis=1))
# Convert to list is good as it is above?
            window_masked_im.shape[0:2])
        window_pixel_size = np.array([xres, yres]) / scaling_factor  # (um, um)

        # resize the images to training window size
        window_im = cytometer.utils.resize(window_im,
                                           size=training_size,
                                           resample=Image.LINEAR)
        window_masked_im = cytometer.utils.resize(window_masked_im,
                                                  size=training_size,
                                                  resample=Image.LINEAR)
        window_seg_gtruth = cytometer.utils.resize(window_seg_gtruth,
                                                   size=training_size,
                                                   resample=Image.NEAREST)

        # compute texture vectors per channel
        window_features = (haralick(window_masked_im[:, :, 0].astype(np.uint8),
                                    ignore_zeros=True),
                           haralick(window_masked_im[:, :, 1].astype(np.uint8),
                                    ignore_zeros=True),
                           haralick(window_masked_im[:, :, 2].astype(np.uint8),
                                    ignore_zeros=True))
        window_features = np.vstack(window_features)
        window_features = window_features.flatten()

        # add dummy dimensions for keras
        window_im = np.expand_dims(window_im, axis=0)
        window_masked_im = np.expand_dims(window_masked_im, axis=0)
        window_seg_gtruth = np.expand_dims(window_seg_gtruth, axis=0)

        # scale image values to float [0, 1]
        window_im = window_im.astype(np.float32)
        window_im /= 255
Ejemplo n.º 35
0
def getFeatures(grayROI, binaryROI, objContour):
    # features are first converted to lists which makes them easier to append
    # at the end of the function, they are converted to a numpy vector (1xN)
    featureList = []

    #SHAPE
    # area
    area = cv2.contourArea(objContour)

    # aspect ratio
    ((x0, y0), (w, h), theta) = cv2.minAreaRect(
        objContour
    )  # from https://www.programcreek.com/python/example/89463/cv2.minAreaRect
    if w == 0 or h == 0:
        aspectRatio = 0
    elif w >= h:
        aspectRatio = float(w) / h
    else:
        aspectRatio = float(h) / w

    # solidity
    hull = cv2.convexHull(objContour)
    hull_area = cv2.contourArea(hull)
    solidity = float(area) / hull_area

    # ellipse
    (xe, ye), (eMajor, eMinor), angle = cv2.fitEllipse(objContour)

    # contour
    contourLen = len(objContour)
    mean = np.mean(objContour)
    std = np.std(objContour)
    perimeter = cv2.arcLength(objContour, True)

    # circle
    (xc, yc), radius = cv2.minEnclosingCircle(objContour)

    # texture
    edgeIM = cv2.Canny(grayROI, 100, 200)  # edge_detection
    onPix = np.sum(edgeIM) / 255
    (h, w) = grayROI.shape
    texture = float(onPix / (w * h))
    shape = [
        area, aspectRatio, texture, solidity, eMajor, eMinor, contourLen,
        perimeter, radius, mean, std
    ]
    featureList.append(shape)

    # HU MOMENTS
    moments = cv2.moments(binaryROI)
    hu = cv2.HuMoments(moments)
    huMoments = -np.sign(hu) * np.log10(np.abs(hu))
    huMoments = huMoments[:, 0]
    featureList.append(huMoments.tolist())

    # ZERNIKE MOMENTS
    W, H = grayROI.shape
    R = min(W, H) / 2
    z = zernike_moments(grayROI, R, 8)
    zsum = np.sum(z[1:])
    z[0] = zsum  # first Zernike moment always constant so replace with sum
    featureList.append(z.tolist())

    # HARALICK FEATURES
    har = haralick(grayROI)
    haralickMean = har.mean(axis=0)
    featureList.append(haralickMean[1:].tolist())  # first entry is usually 0

    # GRAYSCALE HISTOGRAM
    grayHist = np.zeros((5))
    histogram = cv2.calcHist([grayROI], [0], None, [255], [0, 255])
    grayHist[0] = histogram.mean()
    grayHist[1] = histogram.std()
    grayHist[2] = skew(histogram)
    grayHist[3] = kurtosis(histogram)
    histNorm = histogram / np.max(histogram)
    grayHist[4] = entropy(histNorm)
    featureList.append(grayHist.tolist())

    # LOCAL BINARY PATTERNS
    eps = 1e-7  # so we don't divide by zero
    radius = 8
    points = 8 * radius  # Number of points to be considered as neighbourers
    lbp = feature.local_binary_pattern(grayROI,
                                       points,
                                       radius,
                                       method='uniform')  # Uniform LBP is used
    (hist, _) = np.histogram(lbp.ravel(),
                             bins=np.arange(0, points + 3),
                             range=(0, points + 2))
    hist = hist.astype("float")
    lbpHist = hist / (hist.sum() + eps)  # normalize the histogram
    a = lbpHist[
        0:
        6]  # take the first 6 values and last 2 values, the rest are usually 0
    b = lbpHist[-2:]
    c = np.concatenate((a, b))
    featureList.append(c.tolist())

    # convert featureList to featureVector (a numpy array 1xN)
    ff = featureList[0] + featureList[1] + featureList[2] + featureList[
        3] + featureList[4] + featureList[5]
    featureVector = np.array([ff])
    #print('featureVector shape',featureVector.shape)
    return (featureVector)