Использование cv::erode с небольшим ядром и несколькими итерациями может быть достаточным для ваших нужд, даже если это не точно.
Код С++:
cv::Mat img = ...;
int iterations = 10;
cv::erode(img, img,
cv::getStructuringElement(cv::MORPH_RECT, cv::Size(3,3)),
cv::Point(-1,-1),
iterations);
Демо:
# img is the image containing the original black contour
for form in [cv.MORPH_RECT, cv.MORPH_CROSS]:
eroded = cv.erode(img, cv.getStructuringElement(form, (3,3)), iterations=10)
contours, hierarchy = cv.findContours(~eroded, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
cv.drawContours(vis, contours, 0, (0,0,255))
cv.drawContours(vis, contours, 1, (255,0,0))
show_image(vis)
10 итераций cv.MORPH_RECT с ядром 3x3:
![MORPH_RECT](https://i.stack.imgur.com/STGqA.png)
10 итераций cv.MORPH_CROSS с ядром 3x3:
![MORPH_CROSS](https://i.stack.imgur.com/X1hvv.png)
Вы можете изменить смещение, отрегулировав количество итераций.
Гораздо более точным подходом было бы использование cv::distanceTransform для поиска всех пикселей, которые находятся примерно в 10 пикселях от контура:
dist = cv.distanceTransform(img, cv.DIST_L2, cv.DIST_MASK_PRECISE)
ring = cv.inRange(dist, 9.5, 10.5) # take all pixels at distance between 9.5px and 10.5px
show_image(ring)
contours, hierarchy = cv.findContours(ring, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
cv.drawContours(vis, contours, 0, (0,0,255))
cv.drawContours(vis, contours, 2, (255,0,0))
show_image(vis)
![distanceTransform](https://i.stack .imgur.com/PWFJ9.png)
Вы получите два контура с каждой стороны исходного контура. Используйте findContours с RETR_EXTERNAL, чтобы восстановить только внешний контур. Чтобы также восстановить внутренний контур, используйте RETR_LIST
person
Stefan Dragnev
schedule
27.03.2019
cv::dilate
илиcv::erode
будут выполнять работу в определенной степени (или в деталях). Сверхтонкое решение будет включать в себя что-то вроде нахождения центра масс, проецированияx, y
координат исходного контура в правильном направлении и определения новыхx, y
координат для результирующего контура, таким образом, я предполагаю, что будет много интерполяции и экстраполяции. - person HansHirse   schedule 27.03.2019