我想寫一個代碼在python3中檢測圖像的對象形狀。
我想從給定圖像中的對象中選擇一個像素,並找到相鄰像素。
如果它們具有相同的RGB值,表示它們是對象的一部分。
當鄰居像素改變RGB值與原始像素有一個可調差異時,該算法應停止搜索鄰居。我認爲這將工作,除非背景和對象具有相同的顏色。
我已經找到了一種方法可以將相同顏色的像素放在一個矩形中,但這不會對我有幫助。我想保存對象的形狀並將其放入不同的圖像中。
例如,如何使用python3檢測圖像中的對象形狀?
如果我想從一個物體的中間開始我的算法,讓我們 說用白色背景上的黑色表,算法會發現 像素在任何方向的同一顏色。
當相鄰像素的RGB值在一個方向上的變化超過30個單位時,算法將停止朝該方向前進,並且將以另一個方向開始進行,直到我具有該表的形狀。
我發現了另一篇文章,幫助我的像素確定的地區擁有了共同的價值代碼使用PIL
謝謝!
from collections import defaultdict
from PIL import Image, ImageDraw
def connected_components(edges):
"""
Given a graph represented by edges (i.e. pairs of nodes), generate its
connected components as sets of nodes.
Time complexity is linear with respect to the number of edges.
"""
neighbors = defaultdict(set)
for a, b in edges:
neighbors[a].add(b)
neighbors[b].add(a)
seen = set()
def component(node, neighbors=neighbors, seen=seen, see=seen.add):
unseen = set([node])
next_unseen = unseen.pop
while unseen:
node = next_unseen()
see(node)
unseen |= neighbors[node] - seen
yield node
return (set(component(node)) for node in neighbors if node not in seen)
def matching_pixels(image, test):
"""
Generate all pixel coordinates where pixel satisfies test.
"""
width, height = image.size
pixels = image.load()
for x in xrange(width):
for y in xrange(height):
if test(pixels[x, y]):
yield x, y
def make_edges(coordinates):
"""
Generate all pairs of neighboring pixel coordinates.
"""
coordinates = set(coordinates)
for x, y in coordinates:
if (x - 1, y - 1) in coordinates:
yield (x, y), (x - 1, y - 1)
if (x, y - 1) in coordinates:
yield (x, y), (x, y - 1)
if (x + 1, y - 1) in coordinates:
yield (x, y), (x + 1, y - 1)
if (x - 1, y) in coordinates:
yield (x, y), (x - 1, y)
yield (x, y), (x, y)
def boundingbox(coordinates):
"""
Return the bounding box of all coordinates.
"""
xs, ys = zip(*coordinates)
return min(xs), min(ys), max(xs), max(ys)
def disjoint_areas(image, test):
"""
Return the bounding boxes of all non-consecutive areas
who's pixels satisfy test.
"""
for each in connected_components(make_edges(matching_pixels(image, test))):
yield boundingbox(each)
def is_black_enough(pixel):
r, g, b = pixel
return r < 10 and g < 10 and b < 10
if __name__ == '__main__':
image = Image.open('some_image.jpg')
draw = ImageDraw.Draw(image)
for rect in disjoint_areas(image, is_black_enough):
draw.rectangle(rect, outline=(255, 0, 0))
image.show()