简体   繁体   中英

Remove key points from edges of an object

I am working with images with objects in it. I used canny edge detection and contours to detect and draw the edges of the objects in it. Then I used both SIFT and SURF to detect key points in the object. Here is the sample code I've been working on.

import cv2 as cv
import numpy as np 
import matplotlib.pyplot as plt
img = cv.imread(image)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 100,200)
image, contours, hierarchy = cv.findContours(edges, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
outimg = cv.drawContours(img, contours, -1, (0,255,0), 3)
sift = cv.xfeatures2d_SIFT.create()
kp, des = sift.detectAndCompute(outimg,None)

Is there any way to remove the key points that are on the edge? Answer with example will be really helpful. Thanks.

原图 输出图像

You can use pointPolygonTest method to filter detected keypoints. Use detected contours as boundary polygon. You will also be able to define desired margin.

Simaple example (fot 4 point contour):

def inside_point(self, point, rect):

        # point is a list (x, y)
        # rect is a contour with shape [4, 2]

        rect = rect.reshape([4, 1, 2]).astype(np.int64)

        dist = cv2.pointPolygonTest(rect,(point[0], point[1]),True)

        if dist>=0:
            # print(dist)
            return True
        else:
            return False 

You can also draw contours on mask image and to check if the point is inside contours, just check the pixel value with the point coordinates, and if it not 0 then point is valid.

Seems everythig woeks fine: I have no xfeatures2d, so used ORB features here.

import cv2 as cv
import numpy as np 
import matplotlib.pyplot as plt

img = cv.imread('image.jpg')
#img = cv.resize(img,(512,512))
img = cv.copyMakeBorder(img,20,20,20,20, 0)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)

_ , gray = cv.threshold(gray,20,255,cv.THRESH_TOZERO)

gray=cv.erode(gray,np.ones( (5,5), np.int8) )
edges = cv.Canny(gray, 100,200)
contours, hierarchy = cv.findContours(edges, cv.RETR_EXTERNAL, cv.CHAIN_APPROX_SIMPLE)

orb = cv.ORB_create(nfeatures=10000)
kp, des = orb.detectAndCompute(gray,None)

outimg = cv.drawContours(img, contours, -1, (0,255,0), 3)

k = []
for cont in contours:   
    for i in kp: 
        (x, y) =i.pt
        dist = cv.pointPolygonTest(cont, (x,y), True)
        if dist>=0:
            k.append(i)

for i in k:
    pt=(int(i.pt[0]),int(i.pt[1]) )
    cv.circle(outimg,pt,3, (255,255,255),-1)

cv.imwrite('result.jpg',outimg)        
cv.imshow('outimg',outimg)
cv.waitKey()

在此处输入图片说明

I am still finding it difficult to remove key points from the given image. I tried to append the key points in a new list if it's not in the contour but shows an error when I use cv2.drawKeypoints function because the new list is not of type keypoint. This is the work I have done so far.

import cv2 as cv
import numpy as np 
import matplotlib.pyplot as plt
img = cv.imread(image)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
edges = cv.Canny(gray, 100,200)
image, contours, hierarchy = cv.findContours(edges, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
outimg = cv.drawContours(img, contours, -1, (0,255,0), 3)
sift = cv.xfeatures2d_SIFT.create()
kp, des = sift.detectAndCompute(outimg,None)
k = cv.KeyPoint()
for i in kp: 

    (x, y) =i.pt
    dist = cv.pointPolygonTest(contours[0], (x,y), True)
    if dist>=0:
        k1.append(k)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM