python中的图像分割 [英] Image segmentation in python
问题描述
我有图像
我正在寻找python解决方案,以根据图像中的轮廓将图像中的形状分成较小的部分.
I am looking for python solution to break the shape in this image into smaller parts according to the contour in the image.
我已经研究了OpenCV中Canny和findContours的解决方案,但是它们都不适合我.
I have looked into solution on Canny and findContours in OpenCV but none of them works for me.
使用的代码:
import cv2 import numpy as np
img = cv2.imread('area_of_blob_maxcontrast_white.jpg') edges = cv2.Canny(img, 100, 200)
cv2.imwrite('area_of_blob_maxcontrast_white_edges.jpg',edges)
使用findContours方法
import numpy as np
import argparse
import cv2
image = cv2.imread('area_of_blob_maxcontrast_white.png')
lower = np.array([0, 0, 0]) upper = np.array([15, 15, 15]) shapeMask = cv2.inRange(image, lower, upper)
(_,cnts, _) = cv2.findContours(shapeMask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE) print "I found %d black shapes" % (len(cnts)) cv2.imshow("Mask", shapeMask)
for c in cnts:
# draw the contour and show it
cv2.drawContours(image, [c], -1, (0, 255, 0), 2)
cv2.imshow("Image", image)
cv2.waitKey(0)
推荐答案
诀窍是使模糊的单个像素边界稍微大胆.我通过将具有两个相邻黑色像素(上方,下方,左侧或右侧)的任何白色像素更改为黑色来做到这一点.(不过,我的速度非常慢.我敢肯定,必须有一种更聪明的方法来使用OpenCV或Numpy来做到这一点.)
The trick is to make your faint single pixel boundary slightly bolder. I do it by changing any white pixel that has two adjacent black pixels (above, below, to the left or to the right) to black. (I do it extremely slow, though. I'm pretty sure there must be a smarter way to do it with OpenCV or Numpy.)
这是我的代码:
#!/usr/bin/env python
import numpy as np
import cv2
THRESH = 240
orig = cv2.imread("map.png")
img = cv2.cvtColor(orig, cv2.COLOR_BGR2GRAY)
# Make the faint 1-pixel boundary bolder
rows, cols = img.shape
new_img = np.full_like(img, 255) # pure white image
for y in range(rows):
if not (y % 10):
print ('Row = %d (%.2f%%)' % (y, 100.*y/rows))
for x in range(cols):
score = 1 if y > 0 and img.item(y-1, x) < THRESH else 0
score += 1 if x > 0 and img.item(y, x-1) < THRESH else 0
score += 1 if y < rows-1 and img.item(y+1, x) < THRESH else 0
score += 1 if x < cols-1 and img.item(y, x+1) < THRESH else 0
if img.item(y, x) < THRESH or score >= 2:
new_img[y, x] = 0 # black pixels show boundary
cv2.imwrite('thresh.png', new_img)
# Find all contours on the map
_th, contours, hierarchy = cv2.findContours(new_img,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
print "Number of contours detected = %d" % len(contours)
# Fill second level regions on the map
coln = 0
colors = [
[127, 0, 255],
[255, 0, 127],
[255, 127, 0],
[127, 255, 0],
[0, 127, 255],
[0, 255, 127],
]
hierarchy = hierarchy[0]
for i in range(len(contours)):
area = cv2.contourArea(contours[i])
if hierarchy[i][3] == 1:
print (i, area)
coln = (coln + 1) % len(colors)
cv2.drawContours(orig, contours, i, colors[coln], -1)
cv2.imwrite("colored_map.png", orig)
输入图片:
输出图像:
在这里,我仅对最轮廓( hierarchy [i] [3] == 1
)的直接后代进行着色.但是您可以更改它以排除湖泊.
Here I color only the direct descendants of the outmost contour (hierarchy[i][3] == 1
). But you can change it to exclude the lakes.
这篇关于python中的图像分割的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!