2016-03-28 13 views
6

Zacznę gdzie jestem:Jak mogę wypełnić dowolne zamknięte regiony w Matplotlib?

enter image description here

stworzyłem powyższy obraz z następującego kodu:

import matplotlib.pyplot as plt 
import numpy as np 

color_palette_name = 'gist_heat' 
cmap = plt.cm.get_cmap(color_palette_name) 
bgcolor = cmap(np.random.rand()) 

f = plt.figure(figsize=(12, 12), facecolor=bgcolor,) 
ax = f.add_subplot(111) 
ax.axis('off') 

t = np.linspace(0, 2 * np.pi, 1000) 

x = np.cos(t) + np.cos(6. * t)/2.0 + np.sin(14. * t)/3.0 
y = np.sin(t) + np.sin(6. * t)/2.0 + np.cos(14. * t)/3.0 

ax.plot(x, y, color=cmap(np.random.rand())) 
ax.fill(x, y, color=cmap(np.random.rand())) 
plt.tight_layout() 
plt.savefig("../demo/tricky.png", facecolor=bgcolor, edgecolor=cmap(np.random.rand()), dpi=350) 

Czy istnieje sposób, aby wypełnić pętle (lub trójkąt podobny regiony), które powstają, gdy linia przecina się z innym kolorem? Nie musi to być matplotlib, może to być obraz-scikit lub jakaś inna biblioteka.

myślę jakiś pseudo-kodu, takich jak:

for region in regions: 
    ax.fill(region, color=cmap(np.random.rand())) 

Ale nie mam pojęcia jak uzyskać regions, albo jak napełnianie będzie pracować.

Odpowiedz

3

Najpierw problem wydawał mi się prosty, moim pomysłem było wykorzystanie analizy blobów do wykrycia różnych obiektów typu blob, pogrupowanie ich według rozmiaru i użycie algorytmu przepełnienia, aby je pokolorować.

Jednak napotkałem na pewne problemy z domyślnymi wartościami analizy blobów, których nie zmodyfikowałem, co kosztowało trochę czasu. Ponadto, nie znalazłem żadnych fragmentów kodu Pythona do wypełniania powodzi lub colourizing obiektów blob z OpenCV, i były pewne zmiany w składni za pomocą SimpleBlobDetection w porównaniu do starszych wersji, dla których mogłem znaleźć tylko małą dokumentację i przykładowy kod. Może więc cały ten kod może być przydatny również dla innych użytkowników.

Mam nadzieję, że poprawnie zidentyfikowałem segmenty, które chciałeś znaleźć. Jeśli nie chcesz zawierać dużych ciemnych zewnętrznych liści, istnieje linia do komentowania.

Dla wizualizacji, można zmienić rozmiar obrazu (wypowiedziało się w tej chwili, należy pamiętać, aby dostosować progi wielkości odpowiednio przez współczynnik 4 * 4 = 16)

enter image description here

Kod jest nieco dłuższe z tymi wszystkimi opcjami, ale mam nadzieję, że łatwo je przeczytać. Wiele się nauczyłem na temat analizy blobów przy pomocy OpenCV pracującego nad tym problemem, dziękuję!

Przyjemny obraz, przy okazji.

import numpy as np 
import cv2 

im = cv2.imread('tricky.png') 

# For better visibility, resize image to better fit screen 
#im= cv2.resize(im, dsize=(0,0),fx=0.25, fy=0.25) 

#convert to gray value for blob analysis 
imgray= cv2.cvtColor(im,cv2.COLOR_BGR2GRAY) 



#### Blob analysis to find inner white leaves 
# SimpleBlobDetector will find black blobs on white surface, this is why type=cv2.THRESH_BINARY_INV is necessary 
ret,imthresh = cv2.threshold(imgray,160, 255,type=cv2.THRESH_BINARY_INV) 

# Setup SimpleBlobDetector parameters. 
params = cv2.SimpleBlobDetector_Params() 

# Filter by Area. 
params.filterByArea = True 
params.minArea = 15000 
params.maxArea = 150000 

# Create a detector with the parameters 
detector = cv2.SimpleBlobDetector_create(params) 

# Detect blobs. 
keypoints = detector.detect(imthresh) 

# Draw detected blobs as red circles. 
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures 
# the size of the circle corresponds to the size of blob 
im_with_keypoints = cv2.drawKeypoints(imthresh, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) 

# Show blobs 
cv2.imshow("Keypoints", im_with_keypoints) 




####floodfill inner white leaves with blue 
#http://docs.opencv.org/3.0-beta/modules/imgproc/doc/miscellaneous_transformations.html 

#Create a black mask for floodfill. Mask needs to be 2 pixel wider and taller 
maskborder=imgray.copy() 
maskborder[:] = 0 
bordersize=1 
maskborder=cv2.copyMakeBorder(maskborder, top=bordersize, bottom=bordersize, left=bordersize, right=bordersize, borderType= cv2.BORDER_CONSTANT, value=[255,255,255]) 
print imgray.shape[:2] 
print maskborder.shape[:2] 

#Create result image for floodfill 
result = im.copy() 

#fill white inner segments with blue color 
for k in keypoints: 
    print int(k.pt[0]),int(k.pt[1]) 
    seed_pt = int(k.pt[0]),int(k.pt[1]) 
    cv2.floodFill(result, maskborder, seed_pt, (255,0, 0)) 




#### Blob analysis to find small triangles 
# SimpleBlobDetector will find black blobs on white surface, this is why type=cv2.THRESH_BINARY_INV is necessary 
ret,imthresh2 = cv2.threshold(imgray,150, 255,type=cv2.THRESH_BINARY) 
ret,imthresh3 = cv2.threshold(imgray,140, 255,type=cv2.THRESH_BINARY_INV) 
imthresh4 = cv2.add(imthresh2,imthresh3) 

# Setup SimpleBlobDetector parameters. 
params = cv2.SimpleBlobDetector_Params() 

# Filter by Area. 
params.filterByArea = True 
params.minArea = 20 
params.maxArea = 1000 
params.maxArea = 50000 #Using this line includes the outer dark leaves. Comment out if necessary 

# Don't filter by Circularity 
params.filterByCircularity = False 

# Don't filter by Convexity 
params.filterByConvexity = False 

# Don't filter by Inertia 
params.filterByInertia = False 

# Create a detector with the parameters 
detector = cv2.SimpleBlobDetector_create(params) 

# Detect blobs. 
keypoints = detector.detect(imthresh4) 

# Draw detected blobs as red circles. 
# cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS ensures 
# the size of the circle corresponds to the size of blob 
im_with_keypoints2 = cv2.drawKeypoints(imthresh4, keypoints, np.array([]), (0,0,255), cv2.DRAW_MATCHES_FLAGS_DRAW_RICH_KEYPOINTS) 

# Show blobs 
cv2.imshow("Keypoints2", im_with_keypoints2) 



####floodfill triangles with green 
#http://docs.opencv.org/3.0-beta/modules/imgproc/doc/miscellaneous_transformations.html 

#Create a black mask for floodfill. Mask needs to be 2 pixel wider and taller 
maskborder=imgray.copy() 
maskborder[:] = 0 
bordersize=1 
maskborder=cv2.copyMakeBorder(maskborder, top=bordersize, bottom=bordersize, left=bordersize, right=bordersize, borderType= cv2.BORDER_CONSTANT, value=[255,255,255]) 
print imgray.shape[:2] 
print maskborder.shape[:2] 

#Create result image for floodfill 
result2 = result.copy() 

#fill triangles with green color 
for k in keypoints: 
    print int(k.pt[0]),int(k.pt[1]) 
    seed_pt = int(k.pt[0]),int(k.pt[1]) 
    cv2.floodFill(result2, maskborder, seed_pt, (0,255, 0)) 



#cv2.imshow('main',im) 
#cv2.imshow('gray',imgray) 
#cv2.imshow('borders',maskborder) 
#cv2.imshow('threshold2',imthresh2) 
#cv2.imshow('threshold3',imthresh3) 
#cv2.imshow('threshold4',imthresh4) 
cv2.imshow("Result", result2) 
cv2.imwrite("result.png",result2) 

cv2.waitKey(0) 
cv2.destroyAllWindows() 
Powiązane problemy