def opencv_fitEllipse(img, method="Direct"):
    #assert binary_mask.min() >= 0.0 and binary_mask.max() <= 1.0
    # points = np.argwhere(binary_mask == 1)  # TODO: tune threshold

    contours, hierarchy = cv2.findContours(img, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

    # c_img = cv2.drawContours(img, contours, -1, (0, 255, 0), 1)
    # plt.figure()
    # plt.imshow(c_img)
    # plt.show()

    for c in contours:
        ellipse = cv2.fitEllipse(c)

    if method == "AMS":
        for c in contours:
            ellipse = cv2.fitEllipseAMS(c)
    elif method == "Direct":
        for c in contours:
            ellipse = cv2.fitEllipseDirect(c)
    elif method == "Simple":
        for c in contours:
            ellipse = cv2.fitEllipse(c)
    else:
        raise ValueError("Wrong method")

    return ellipse
Exemplo n.º 2
0
def ellipse_heuristic(c, shape):
    # get_convex_hull(laplacian_smoothing(c, n=16))
    c = get_convex_hull(c)
    ellipse = cv2.fitEllipseAMS(np.reshape(c, (-1, 2)))

    e_mask = np.zeros(shape, np.uint8)
    c_mask = np.zeros(shape, np.uint8)
    center_mask = np.zeros(shape, np.uint8)

    e_mask = cv2.ellipse(e_mask, ellipse, 255, -1)
    c_mask = cv2.drawContours(c_mask, [c], -1, 255, -1)
    center_mask = cv2.rectangle(center_mask, (0, 100),
                                (shape[1], shape[0] - 100), 255, -1)

    _, (x, y), _ = ellipse

    if y < x:
        x, y = y, x

    # print x / float(y)

    if x / float(y) < 0.1:
        return 0

    intersection = e_mask & c_mask & center_mask
    union = (e_mask | c_mask) & center_mask

    us = float(np.sum(union))

    if us == 0:
        return 0

    h = np.sum(intersection) / us

    return h
Exemplo n.º 3
0
def ellipse_fit(points, method="Direct"):
    if method == "AMS":
        (xx, yy), (MA, ma), angle = cv2.fitEllipseAMS(points)
    elif method == "Direct":
        (xx, yy), (MA, ma), angle = cv2.fitEllipseDirect(points)
    elif method == "Simple":
        (xx, yy), (MA, ma), angle = cv2.fitEllipse(points)

    return (xx, yy), (MA, ma), angle
Exemplo n.º 4
0
    def detect1(
        self, c
    ):  # I feel like we should get the center in subtract (or right after) and the shape here
        if len(c):
            epsilon = 0.1 * cv2.arcLength(c, True)
            approx = cv2.approxPolyDP(c, epsilon, True)
            cv2.drawContours(self.out, [approx], 0, Color.MAGENTA, 1)

            if len(c) >= 5:
                ellipse_mask = np.zeros((self.h, self.w), dtype=np.uint8)
                rectangle_mask = ellipse_mask.copy()

                #for mask
                rect = cv2.minAreaRect(c)
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                cv2.drawContours(rectangle_mask, [box], 0, 255, -1)

                ellipse = cv2.fitEllipseAMS(c)  #make a fit function iterator
                cv2.ellipse(ellipse_mask, ellipse, 255, -1)

                rect_err_px = cv2.bitwise_xor(self.mask, rectangle_mask)
                circ_err_px = cv2.bitwise_xor(self.mask, ellipse_mask)

                rect_err = cv2.countNonZero(rect_err_px)
                circ_err = cv2.countNonZero(circ_err_px)

                cv2.putText(self.out, "eR: %2.f" % rect_err, (400, 20),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, Color.GREEN, 2)
                cv2.putText(self.out, "eC: %2.f" % circ_err, (400, 40),
                            cv2.FONT_HERSHEY_SIMPLEX, 0.5, Color.YELLOW, 2)

                if rect_err < circ_err:
                    #rectangle
                    cv2.drawContours(self.out, [box], 0, Color.GREEN, 2)
                    self.results[0] = 0
                    #state="TRACING"
                    return False
                else:
                    #circle
                    self.results[0] = 1
                    cv2.ellipse(self.out, ellipse, Color.YELLOW, 2)
                    #state="TRACKING"
                    return False

            else:
                self.results[0] = -1
                return True
            # (x,y),radius = cv2.minEnclosingCircle(c)
            # cv2.circle(ellipse_mask,(int(x),int(y)),int(radius),(0,255,255),2)
            #deficidnt logic will be here
            #after selection

        else:
            self.results[0] = -1
            return True
Exemplo n.º 5
0
    def refine_ellipse(self, segments, idx):
        if len(idx) == 0: return None
        X, Y = [], []
        for i in idx:
            X += segments[i][:, 0].tolist()
            Y += segments[i][:, 1].tolist()

        seg = numpy.vstack((X, Y), ).T
        ellipse = cv2.fitEllipseAMS(seg.astype(numpy.float32))
        return ellipse
Exemplo n.º 6
0
    def estimate_ellipse(self, segments, s1, s2):

        seg = numpy.vstack((segments[s1], segments[s2]))
        ellipse = cv2.fitEllipseAMS(seg)
        if not self.is_good_ellipse(ellipse): return None, []

        ellipse_mask = self.get_ellipse_mask(ellipse)
        is_match = numpy.array([
            self.match_segment_ellipse(segment, ellipse_mask)
            for segment in segments
        ])
        idx_match = numpy.where(is_match)[0]
        return ellipse, idx_match
Exemplo n.º 7
0
def test_EllipseAMS(img):
    imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    ret, binary = cv2.threshold(src=imgray, thresh=180, maxval=255, type=cv2.THRESH_BINARY)

    find = np.where(binary == 255)  # return tuple
    cnt = np.vstack(find).T
    cnt = cnt[:, np.newaxis, :][:, :, ::-1]  # (6000, 1, 2)

    # 并不是把所有点都包裹进去
    ellipse = cv2.fitEllipseAMS(cnt)

    # cvt binary to 3-channels
    for i in range(img.shape[0]):
        for j in range(img.shape[1]):
            img[i][j] = [binary[i][j], binary[i][j], binary[i][j]]

    cv2.ellipse(img, ellipse, color=(0, 255, 0), thickness=2)
    cv2.imshow('fitEllipseAMS', img)
Exemplo n.º 8
0
    def estimate_ellipse(self, segments, s1, s2=None):
        if s2 is not None:
            seg = numpy.vstack((segments[s1], segments[s2]))
        else:
            seg = segments[s1]

        ellipse = cv2.fitEllipseAMS(seg)
        if not self.is_good_ellipse(ellipse): return None, []
        ellipse_mask = self.get_ellipse_mask(ellipse)

        #match1 = self.match_segment_ellipse(segments[s1], ellipse_mask)
        #match2 = self.match_segment_ellipse(segments[s2], ellipse_mask)
        #if not (match1 and match2): return None,[]

        is_match = numpy.array([
            self.match_segment_ellipse(segment, ellipse_mask)
            for segment in segments
        ])
        idx_match = numpy.where(is_match)[0]
        return ellipse, idx_match
def bboxes(path):

    name = 'Boxer'
    cv2.namedWindow(name)
    # cv2.resizeWindow(name, 800,600)
    cv2.moveWindow(name, 100, 960)
    #blr=cv2.blur(img, (5,5))

    cv2.createTrackbar('blur', name, 0, 5, nothing)
    cv2.createTrackbar('sig_space', name, 0, 120, nothing)
    cv2.createTrackbar('sig_color', name, 0, 120, nothing)
    cv2.createTrackbar('canny', name, 0, 100, nothing)

    #flags
    fancy = 0
    org = 0
    draw = 0
    can = 1

    #vars
    b = 1
    ss = 20
    sc = 20
    t = 50
    #index
    idx = 0
    images = os.listdir(path)
    bg = cv2.imread('bg.jpg')

    for filename in images:
        print("Loading ", filename)
        img = cv2.imread(path + '/' + filename)
        #cv2.imshow(name, img)
        cv2.imshow("Subtracted", cv2.subtract(bg, img))
        while (1):
            if fancy:
                blr = cv2.bilateralFilter(img, b, ss, sc)
            else:
                blr = cv2.blur(img, (b, b))

            if can:
                binary = cv2.Canny(blr, t, 3 * t)
            else:
                gray = cv2.cvtColor(blr, cv2.COLOR_BGR2GRAY)
                (t, binary) = cv2.threshold(gray, t, 255,
                                            cv2.THRESH_BINARY_INV)

            m2, contours, hierarchy = cv2.findContours(binary, cv2.RETR_CCOMP,
                                                       cv2.CHAIN_APPROX_SIMPLE)
            N = len(contours)  # number of conoturs
            if org:
                out = img.copy()
            else:
                out = cv2.cvtColor(binary, cv2.COLOR_GRAY2BGR)

            if draw and N:
                # safety

                c = contours[idx % N]  # better safe then sorry

                #approx here
                cv2.drawContours(out, contours, -1, (0, 255, 0), 4)
                cv2.drawContours(out, [c], 0, (0, 0, 255), 4)
                (x, y, w, h) = cv2.boundingRect(c)
                cv2.rectangle(out, (x, y), (x + w, y + h), (255, 200, 100), 2,
                              1)

                if len(c) >= 5:
                    ellipse = cv2.fitEllipseAMS(
                        c)  #make a fit function iterator
                    cv2.ellipse(out, ellipse, (0, 255, 255), 2)
                # Rotated box
                # rect = cv.minAreaRect(cnt)
                # box = cv.boxPoints(rect)
                # box = np.int0(box)
                # cv.drawContours(img,[box],0,(0,0,255),2)

            cv2.putText(out, str(len(contours)), (20, 20),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.75, (0, 0, 255), 2)
            cv2.imshow(name, out)

            k = cv2.waitKey(30) & 0xFF

            if k == ord('x'):
                exit()
            elif k == ord('b'):
                fancy ^= 1
                print("fancy blur: " + str(fancy))

            elif k == ord('v'):
                org ^= 1
                print("showing original img:" + str(org))

            elif k == ord('c'):
                draw ^= 1
                print("drawing contours: " + str(draw))

            elif k == ord('m'):
                can ^= 1
                print("canny vs threshold: " + str(can))

            elif k == ord('a'):
                idx = (idx + 1) % len(contours)
                print("Drawing ROI #" + str(idx))

            #next image
            elif k == ord('.'):
                print("Next image")
                break

            b = 2 * cv2.getTrackbarPos('blur', name) + 1
            ss = cv2.getTrackbarPos('sig_space', name)
            sc = cv2.getTrackbarPos('sig_color', name)
            t = cv2.getTrackbarPos('canny', name)

#def main():

    cv2.destroyAllWindows()
    mask[labels == label] = 255

    # detect contours in the mask and grab the largest one
    cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
                            cv2.CHAIN_APPROX_SIMPLE)
    cnts = imutils.grab_contours(cnts)
    c = max(cnts, key=cv2.contourArea)

    # draw a circle enclosing the object
    #((x, y), r) = cv2.minEnclosingCircle(c)
    #cv2.circle(image, (int(x), int(y)), int(r), (0, 255, 0), 2)
    #cv2.putText(image, "#{}".format(label), (int(x) - 10, int(y)),
    #	cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

    # ellipse attempt
    (x, y), (MA, ma), angle = cv2.fitEllipseAMS(c)
    cv2.ellipse(image, (int(round(x)), int(round(y))),
                (int(round(MA / 2)), int(round(ma / 2))), int(round(angle)), 0,
                360, (0, 255, 0), 2)
    #cv2.putText(image, "#{}".format(label), (int(x) - 10, int(y)),
    #	cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255), 2)

    # cv2.circle(img, center, radius, color[, thickness[, lineType[, shift]]]) → Non
    # cv2.ellipse(img, center, axes, angle, startAngle, endAngle, color[, thickness[, lineType[, shift]]]) → None

# show the output image
#cv2.imshow("Output", image)
#cv2.waitKey(0)

# save image
status = cv2.imwrite('testresult.png', image)
Exemplo n.º 11
0
def fit(TextoutFile, TextColorFile, PathClean):

    TextoutFileEx = os.path.basename(TextoutFile)
    TextFile = os.path.splitext(TextoutFileEx)[0]

    TextColorFileEx = os.path.basename(TextColorFile)
    TextCFile = os.path.splitext(TextColorFileEx)[0]
    print("------------------------- Fit & Crop -------------------------")
    print(TextFile)

    img = cv2.imread(TextoutFile)
    img2 = cv2.imread(TextColorFile)
    rows, cols = img.shape[:2]

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, threshold = cv2.threshold(gray, 20, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C,
                                 cv2.THRESH_BINARY_INV)

    contours, hierarchy = cv2.findContours(threshold, cv2.RETR_LIST,
                                           cv2.CHAIN_APPROX_SIMPLE)
    print("contours :", len(contours))
    minpass = rows * cols
    check = 0
    stand = 0
    OldAngle = 0

    for cnt in contours:
        area = cv2.contourArea(cnt)
        if 200 < area < 0.4 * rows * cols:
            if area < minpass:
                print("--------------------------")
                print("ALL :", 0.4 * rows * cols)
                print("Letter :", area)
                rect = cv2.minAreaRect(cnt)
                #print(rect)
                box = cv2.boxPoints(rect)
                box = np.int0(box)
                ##            cv2.drawContours(threshold,[box],0,(0,0,255),2)
                ##            cv2.imshow("threshold",threshold)
                ellipse = cv2.fitEllipse(cnt)
                (x, y), (MA, ma), OldAngle = cv2.fitEllipseAMS(cnt)

                # get width and height of the detected rectangle
                width = int(rect[1][0])
                height = int(rect[1][1])

                src_pts = box.astype("float32")
                # corrdinate of the points in box points after the rectangle has been straightened
                dst_pts = np.array([[0, height - 1], [0, 0], [width - 1, 0],
                                    [width - 1, height - 1]],
                                   dtype="float32")

                # the perspective transformation matrix
                M = cv2.getPerspectiveTransform(src_pts, dst_pts)

                # directly warp the rotated rectangle to get the straightened rectangle
                warped = cv2.warpPerspective(img, M, (width, height))
                warped2 = cv2.warpPerspective(img2, M, (width, height))
                # put warped in bigger black picture

                h, w = warped.shape[:2]

                if h > w:
                    size = h + 50
                else:
                    size = w + 50

                Black = np.zeros((size, size, 3), np.uint8)
                Grey = np.zeros((size, size, 3), np.uint8)
                Grey[:] = (100, 100, 100)
                try:
                    Black[int(size / 2 - h / 2):int(size / 2 + h / 2),
                          int(size / 2 - w / 2):int(size / 2 + w / 2)] = warped
                    # kernel_sharpening = np.array([[-1,-1,-1],[-1, 9,-1],[-1,-1,-1]])
                    # Black = cv2.filter2D(Black, -1, kernel_sharpening)
                    Grey[int(size / 2 - h / 2):int(size / 2 + h / 2),
                         int(size / 2 - w / 2):int(size / 2 + w / 2)] = warped2

                    cv2.imwrite("%s/%sclean.jpg" % (PathClean, TextFile),
                                Black)
                    print("%s/%sclean.jpg" % (PathClean, TextFile))
                    TextClean = ("%s/%sclean.jpg" % (PathClean, TextFile))

                    cv2.imwrite("%s/%scolor.jpg" % (PathClean, TextFile), Grey)
                    print("%s/%scolor.jpg" % (PathClean, TextFile))
                    Textcolor = ("%s/%scolor.jpg" % (PathClean, TextFile))
                except Exception:
                    print(
                        "------------ Error! Error! Error! Error! Error! ------------"
                    )
                    continue
                check += 1
                minpass = area
    stand += 1
    if stand > check:
        print("ALL :", 0.6 * rows * cols)
        print("***No Text Found!!!!***")
        print("Letter :", area)
        check = stand
        size = 400
        Black = np.zeros((size, size, 3), np.uint8)
        Grey = np.zeros((size, size, 3), np.uint8)
        Grey[:] = (100, 100, 100)
        cv2.imwrite("%s/%s[Not]clean.jpg" % (PathClean, TextFile), Black)
        print("Not Found :%s/%sOverclean.jpg" % (PathClean, TextFile))
        TextClean = ("%s/%s[Not]clean.jpg" % (PathClean, TextFile))

        cv2.imwrite("%s/%s[Not]color.jpg" % (PathClean, TextFile), Grey)
        print("%s/%sOvercolor.jpg" % (PathClean, TextFile))
        Textcolor = ("%s/%s[Not]color.jpg" % (PathClean, TextFile))

    return TextClean, Textcolor, OldAngle
Exemplo n.º 12
0
def detect_ellipse(img):
    """
    This function computes an image with a pixel set at the largest "wye" detected in the image
    The function returns the binary wye detection image, the threshold image, the smoothed contour, 
    and the skeleton images as a tuple
    """

    # apply a slight blur to help thresholding
    img = cv2.medianBlur(img, 5)

    h, w = np.shape(img)

    # apply adaptive thresholding to find lines
    thresh = 255 - cv2.adaptiveThreshold(
        img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 63, 15)

    # mask out some areas we wish to ignore (eg robot and horizon)
    thresh = cv2.ellipse(thresh, (w / 2, h), (400, 100), 0, 0, 360, (0, 0, 0),
                         -1)
    thresh = cv2.rectangle(thresh, (0, 0), (w, 60), (0, 0, 0), -1)
    # thresh = cv2.rectangle(thresh, (0, 3*h/4), (w/4, h), (0,0,0), -1)
    # thresh = cv2.rectangle(thresh, (3*w/4, 3*h/4), (w, h), (0,0,0), -1)

    detect = np.zeros(thresh.shape, np.uint8)
    closed = np.zeros(thresh.shape, np.uint8)

    contours, heirarchy = cv2.findContours(thresh, cv2.RETR_TREE,
                                           cv2.CHAIN_APPROX_SIMPLE)

    contours = filter(lambda c: len(c) > 50, contours)
    # contours = map(lambda c: get_convex_hull(c), contours)

    contours = filter(lambda c: cv2.contourArea(get_convex_hull(c)) > 10000,
                      contours)
    contours = filter(lambda c: ellipse_heuristic(c, img.shape) > 0.7,
                      contours)

    ellipse = None

    if len(contours) > 0:

        # for c in contours:
        #     print cv2.contourArea(get_convex_hull(c)), ellipse_heuristic(c, img.shape)

        # largest = max(contours, key = lambda c: ellipseScore(c))
        largest = max(
            contours,
            key=lambda c: math.sqrt(cv2.contourArea(get_convex_hull(c))
                                    ) * ellipse_heuristic(c, img.shape))
        # largest = max(contours, key = lambda c: cv2.contourArea(c))
        # largest = contours[]

        largest = laplacian_smoothing(largest, n=16)
        largest = get_convex_hull(largest)

        ellipse = cv2.fitEllipseAMS(np.reshape(largest, (-1, 2)))

        detect = cv2.ellipse(detect, ellipse, (255, 255, 255), -1)

        closed = cv2.drawContours(closed, [largest], -1, (255, 255, 255), -1)

    return ellipse, detect, thresh, closed
Exemplo n.º 13
0
totImg = img.copy()
for i in range(len(contours)):
    # 外接圆 - 红色
    imgCp = img.copy()
    (x, y), radius = cv2.minEnclosingCircle(contours[i])
    (x, y, radius) = np.int0((x, y, radius))  # 圆心和半径取整
    cv2.circle(imgCp, (x, y), radius, (0, 0, 255), 2)

    # 拟合椭圆,方法返回的是一个RotatedRectangle,拟合的椭圆即为其内切椭圆
    # 青色
    ellipse = cv2.fitEllipse(contours[i])
    cv2.ellipse(imgCp, ellipse, (255, 255, 0), 2)

    # 拟合椭圆的另外两种方法
    # 蓝色
    ellipse = cv2.fitEllipseAMS(contours[i])
    cv2.ellipse(imgCp, ellipse, (255, 0, 0), 2)
    # 绿色
    ellipse = cv2.fitEllipseDirect(contours[i])
    cv2.ellipse(imgCp, ellipse, (0, 255, 0), 2)
    totImg = cv2.hconcat((totImg, imgCp))

cv2.imshow('Bounding Circle', totImg)


# 考察轮廓的外接多边形
totImg = img.copy()
for i in range(len(contours)):
    # 多边形逼近,得到多边形的角点。使用Douglas-Peucker算法
    imgCp = img.copy()
    # epsilon表示近似多边形周长和源轮廓周长之间的差值,越小则多边形与源轮廓越相似
Exemplo n.º 14
0
    def process_sample(self):
        #--------------------------------------------Processamento da imagem--------------------------------------------
        #-Normalização da imagem para o intervalo 0 a 255-
        img = cv2.normalize(self.img,
                            None,
                            alpha=0,
                            beta=255,
                            norm_type=cv2.NORM_MINMAX)
        #-Redimensionamento da imagem para 256x256 pelo método de interpolação de área-
        img = cv2.resize(img, (256, 256), interpolation=cv2.INTER_AREA)
        #-Remoção de ruído da imagem-
        blur_img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
        blur_img = cv2.GaussianBlur(blur_img, (7, 7), 0)
        #-Divisão dos canais da imagem-
        _, _, b = cv2.split(blur_img)

        #-Segmentação da imagem através de limiarização do canal B (método de Otsu)-
        th, mask = cv2.threshold(b, 0, 255,
                                 cv2.THRESH_BINARY + cv2.THRESH_OTSU)

        cv2.imwrite('maskb.jpeg', mask)

        #-Gera um kernel elipsóide 3x3-
        kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (3, 3))
        #-Aplica 5 iterações da operação morfológica de fechamento na máscara, utilizando o kernel criado-
        mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=5)

        #-Obtem os contornos da máscara-
        _, cnt, _ = cv2.findContours(mask, cv2.RETR_TREE,
                                     cv2.CHAIN_APPROX_SIMPLE)
        #-Encontra o maior contorno em relação à sua área-
        max_cnt = max(cnt, key=cv2.contourArea)
        #-Define os parâmetros do menor retângulo que englobe o maior contorno encontrado-
        x, y, w, h = cv2.boundingRect(max_cnt)

        #-Combinação das imagens com a máscara para obtenção da Região de Interesse (ROI)-
        #-Imagem original (BGR)-
        img = cv2.bitwise_and(img, img, mask=mask)

        #-Recorta as imagens utilizando os parâmetros do retângulo obtido anteriormente-
        #-Recorte da imagem original-
        img = img[y:y + h, x:x + w]
        self.img_masked = img
        #-Recorta também a máscara utilizando os mesmos parâmetros-
        mask_rsz = mask[y:y + h, x:x + w]
        #-Redimensionamento das imagens para 256x256 pelo método de interpolação cúbica-
        #-Redimensionamento da imagem original-
        img = cv2.resize(img, (256, 256), interpolation=cv2.INTER_CUBIC)
        #-Redimensionamento da imagem L*a*b*-
        LAB_img = cv2.cvtColor(img, cv2.COLOR_BGR2LAB)
        #-Redimensionamento da máscara-
        mask_rsz = cv2.resize(mask_rsz, (256, 256),
                              interpolation=cv2.INTER_NEAREST)

        #----------------------------------------Fim do processamento da imagem-----------------------------------------

        #------------------------------------------Extração de características------------------------------------------
        b, g, r = cv2.split(img)
        LAB_L, LAB_a, LAB_b = cv2.split(LAB_img)
        mask_rsz = cv2.bitwise_not(mask_rsz)
        #-------------DESCRITOR DE COR------------
        LAB_a_ma = np.ma.masked_array(LAB_a, mask=mask_rsz)
        LAB_b_ma = np.ma.masked_array(LAB_b, mask=mask_rsz)

        LAB_a_hist = np.histogram(LAB_a_ma.compressed().ravel(),
                                  bins=np.arange(0, 256),
                                  density=True)
        LAB_b_hist = np.histogram(LAB_b_ma.compressed().ravel(),
                                  bins=np.arange(0, 256),
                                  density=True)
        #-----------DESCRITOR DE TEXTURA----------
        #-Extrair o descritor de textura (Local Binary Patterns) dos canais da imagem RGB-
        LBP_b = feature.local_binary_pattern(b, LBP_pontos, LBP_raio,
                                             'uniform')
        LBP_g = feature.local_binary_pattern(g, LBP_pontos, LBP_raio,
                                             'uniform')
        LBP_r = feature.local_binary_pattern(r, LBP_pontos, LBP_raio,
                                             'uniform')

        LBP_b_ma = np.ma.masked_array(LBP_b, mask=mask_rsz)
        LBP_g_ma = np.ma.masked_array(LBP_g, mask=mask_rsz)
        LBP_r_ma = np.ma.masked_array(LBP_r, mask=mask_rsz)

        #-Gerar o histograma do LBP dos canais RGB-
        LBP_hist_b = np.histogram(LBP_b_ma.compressed().ravel(),
                                  bins=np.arange(0,
                                                 LBP_b_ma.max() + 1),
                                  density=True)
        LBP_hist_g = np.histogram(LBP_g_ma.compressed().ravel(),
                                  bins=np.arange(0,
                                                 LBP_b_ma.max() + 1),
                                  density=True)
        LBP_hist_r = np.histogram(LBP_r_ma.compressed().ravel(),
                                  bins=np.arange(0,
                                                 LBP_b_ma.max() + 1),
                                  density=True)

        #-----------DESCRITOR DE TAMANHO----------
        #-Obtém o elipsoide que melhor se encaixa ao contorno-
        try:
            elipse = cv2.fitEllipseAMS(max_cnt)
        except cv2.error as e:
            print("ERRO ao obter elipse")
        else:
            #Extrai os valores dos eixos da elipse
            _, self.other_features, _ = elipse
        #----------VETOR DE CARACTERÍSTICAS---------
        #-Expande o vetor de características com o histograma dos canais 'a' e 'b' da imagem L*a*b-
        self.feature_vector.extend(LAB_a_hist[0].flatten())
        self.feature_vector.extend(LAB_b_hist[0].flatten())
        #-Expande o vetor de características com o histograma da imagem LBP-
        self.feature_vector.extend(LBP_hist_b[0].flatten())
        self.feature_vector.extend(LBP_hist_g[0].flatten())
        self.feature_vector.extend(LBP_hist_r[0].flatten())