很难尝试对3D对象进行形状识别

时间:2015-10-09 20:36:28

标签: opencv image-processing 3d classification object-recognition

我正在尝试制作一个形状识别分类器,如果你给出一个物体的单独图片(来自一个场景),它就能够(在机器学习之后)对物体的形状进行分类(圆柱体,立方体,球体等)。

原创场景: 1

它将分类的单个对象:

2]

3]

4]

5]

我尝试使用cv2.approxPolyDB尝试对圆柱进行分类。但是,要么我的实现不好,要么首先选择算法不是一个很好的选择,圆柱体形状的对象被赋值为3或4的近似值。

也许我可以阈值,一般来说,如果给定值为3或4,假设对象是圆柱体,但我觉得它不是最可靠的3D形状分类方法。我觉得有更好的方法来实现这个和更好的方法,而不是仅仅硬编码值。我觉得用这种方法,它很容易混淆圆柱体和立方体。

有什么方法可以改进我的3D形状识别程序吗?

代码:

import cv2
import numpy as np
from pyimagesearch import imutils
from PIL import Image
from time import time

def invert_img(img):
    img = (255-img)
    return img

def threshold(im):
    imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
    imgray = cv2.medianBlur(imgray,9)
    imgray = cv2.Canny(imgray,75,200)

    return imgray

def view_all_contours(im, size_min, size_max):
    main = np.array([[]])
    cnt_target = im.copy()

    for c in cnts:
        epsilon = 0.1*cv2.arcLength(c,True)
        approx = cv2.approxPolyDP(c,epsilon,True)
        area = cv2.contourArea(c)
        print 'area: ', area
        test = im.copy()




        # To weed out contours that are too small or big
        if area > size_min and area < size_max:
            print c[0,0]
            print 'approx: ', len(approx)
            max_pos = c.max(axis=0)
            max_x = max_pos[0,0]
            max_y = max_pos[0,1]

            min_pos = c.min(axis=0)
            min_x = min_pos[0,0]
            min_y = min_pos[0,1]



            # Load each contour onto image
            cv2.drawContours(cnt_target, c, -1,(0,0,255),2)


            print 'Found object'

            frame_f = test[min_y:max_y , min_x:max_x]

            main = np.append(main, approx[None,:][None,:])

            thresh = frame_f.copy()
            thresh = threshold(thresh)

            contours_small, hierarchy = cv2.findContours(thresh.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
            cnts_small = sorted(contours_small, key = cv2.contourArea, reverse = True)
            cv2.drawContours(frame_f, cnts_small, -1,(0,0,255),2)
            cv2.imshow('Thresh', thresh)
            cv2.imshow('Show Ya', frame_f)
            cv2.waitKey(0)





        # Uncomment in order to show all rectangles in image


    print '---------------------------------------------'
    #cv2.drawContours(cnt_target, cnts, -1,(0,255,0),2)
    print main.shape
    print main
    return cnt_target



time_1 = time()


roi = cv2.imread('images/beach_trash_3.jpg')

hsv = cv2.cvtColor(roi,cv2.COLOR_BGR2HSV)

target = cv2.imread('images/beach_trash_3.jpg')
target = imutils.resize(target, height = 400)

hsvt = cv2.cvtColor(target,cv2.COLOR_BGR2HSV)

img_height = target.shape[0]
img_width = target.shape[1]

# calculating object histogram
roihist = cv2.calcHist([hsv],[0, 1], None, [180, 256], [0, 180, 0, 256] )

# normalize histogram and apply backprojection
cv2.normalize(roihist,roihist,0,255,cv2.NORM_MINMAX)
dst = cv2.calcBackProject([hsvt],[0,1],roihist,[0,180,0,256],1)

# Now convolute with circular disc
disc = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))
cv2.filter2D(dst,-1,disc,dst)

# threshold and binary AND
ret,thresh = cv2.threshold(dst,50,255,0)
thresh_one = thresh.copy()
thresh = cv2.merge((thresh,thresh,thresh))
res = cv2.bitwise_and(target,thresh)

# Implementing morphological erosion & dilation
kernel = np.ones((9,9),np.uint8)  # (6,6) to get more contours (9,9) to reduce noise
thresh_one = cv2.erode(thresh_one, kernel, iterations = 3)
thresh_one = cv2.dilate(thresh_one, kernel, iterations=2)


# Invert the image
thresh_one = invert_img(thresh_one)


# To show prev img

#res = np.vstack((target,thresh,res))
#cv2.imwrite('res.jpg',res)

#cv2.waitKey(0)


#cv2.imshow('Before contours', thresh_one)

cnt_target = target.copy()
cnt_full = target.copy()

# Code to draw the contours
contours, hierarchy = cv2.findContours(thresh_one.copy(),cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cnts = sorted(contours, key = cv2.contourArea, reverse = True)

print time() - time_1

size_min = 200
size_max = 5000

cnt_target = view_all_contours(target, size_min, size_max)
cv2.drawContours(cnt_full, cnts, -1,(0,0,255),2)


res = imutils.resize(thresh_one, height = 700)
cv2.imshow('Original image', target)
cv2.imshow('Preprocessed', thresh_one)
cv2.imshow('All contours', cnt_full)
cv2.imshow('Filtered contours', cnt_target)

cv2.waitKey(0)

0 个答案:

没有答案