简体   繁体   English

从对象的边缘删除关键点

[英]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.然后我同时使用 SIFT 和 SURF 来检测对象中的关键点。 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.您可以使用pointPolygonTest方法来过滤检测到的关键点。 Use detected contours as boundary polygon.使用检测到的轮廓作为边界多边形。 You will also be able to define desired margin.您还可以定义所需的保证金。

Simaple example (fot 4 point contour):简单示例(4 点轮廓):

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.您还可以在蒙版图像上绘制轮廓并检查点是否在轮廓内,只需检查点坐标的像素值,如果不是 0 则点有效。

Seems everythig woeks fine: I have no xfeatures2d, so used ORB features here.似乎一切都很好:我没有 xfeatures2d,所以在这里使用 ORB 功能。

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.如果关键点不在轮廓中,我尝试将关键点附加到新列表中,但在使用 cv2.drawKeypoints 函数时显示错误,因为新列表不是关键点类型。 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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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