Удалить ключевые точки с краев объекта - PullRequest
0 голосов
/ 22 марта 2020

Я работаю с изображениями с объектами в нем. Я использовал хитрое обнаружение краев и контуры, чтобы обнаружить и нарисовать края объектов в нем. Затем я использовал 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)

Есть ли способ убрать ключевые точки, которые находятся на краю? Ответ с примером будет действительно полезным. Спасибо.

Original Image output image

Ответы [ 2 ]

1 голос
/ 20 апреля 2020

Мне все еще трудно удалить ключевые точки из данного изображения. Я попытался добавить ключевые точки в новый список, если он не находится в контуре, но показывает ошибку, когда я использую функцию cv2.drawKeypoints, потому что новый список не имеет типа keypoint. Это работа, которую я проделал до сих пор.

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)
1 голос
/ 22 марта 2020

Вы можете использовать метод pointPolygonTest для фильтрации обнаруженных ключевых точек. Используйте обнаруженные контуры в качестве граничного многоугольника. Вы также сможете определить желаемое поле.

Пример Sample (для 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()

enter image description here

...