【问题标题】:Remove key points from edges of an object从对象的边缘移除关键点
【发布时间】:2020-07-02 23:31:38
【问题描述】:

我正在处理带有对象的图像。我使用精明的边缘检测和轮廓来检测和绘制其中对象的边缘。然后我同时使用 SIFT 和 SURF 来检测对象中的关键点。这是我一直在处理的示例代码。

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)

有什么办法可以去掉边缘的关键点?用例子回答会很有帮助。 谢谢。

【问题讨论】:

  • 您可以在此处添加图片以便更好地了解您的问题。
  • 我已经添加了图片...

标签: python opencv sift surf keypoint


【解决方案1】:

您可以使用pointPolygonTest 方法过滤检测到的关键点。使用检测到的轮廓作为边界多边形。您还可以定义所需的边距。

简单示例(fot 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 

您也可以在蒙版图像上绘制轮廓,并检查点是否在轮廓内,只需检查点坐标的像素值,如果不是0则点有效。

似乎一切都很好: 我没有 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()

【讨论】:

  • 谢谢。举个例子会更有帮助。
  • 已更新,最后还要检查替代解决方案。
  • 我仍然发现很难使用该功能删除关键点。如果关键点不在轮廓中,我尝试将关键点附加到新列表中,但在使用 cv2.drawKeypoints 函数时显示错误,因为新列表不是关键点类型。您介意彻底解释一下您的解决方案吗?
  • 您能否提供代码来重现您当前的问题。并检查你的轮廓。
  • 我在下面的评论中添加了代码...请看...
【解决方案2】:

我仍然发现很难从给定图像中删除关键点。如果关键点不在轮廓中,我尝试将关键点附加到新列表中,但在使用 cv2.drawKeypoints 函数时显示错误,因为新列表不是关键点类型。这是我迄今为止所做的工作。

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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-01-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多