2012-11-27 135 views
6

Tôi muốn trích xuất hình bóng của một hình ảnh và tôi đang cố gắng thực hiện bằng cách sử dụng chức năng đường bao của MatplotLib. Đây là mã của tôi:Trích xuất đường viền bên ngoài hoặc hình bóng của hình ảnh trong Python

from PIL import Image 
from pylab import * 

# read image to array 
im = array(Image.open('HOJA.jpg').convert('L')) 

# create a new figure 
figure() 

# show contours with origin upper left corner 
contour(im, origin='image') 
axis('equal') 

show() 

Đây là hình ảnh ban đầu của tôi:

Original

Và đây là kết quả của tôi:

Contour

Nhưng tôi chỉ muốn thể hiện bên ngoài đường viền, hình bóng. Chỉ các dòng đọc trong ví dụ này.

Tôi có thể làm như thế nào? Tôi đọc tài liệu của hàm contour, nhưng tôi không thể có được những gì tôi muốn.

Nếu bạn biết cách tốt hơn để làm điều này bằng Python, hãy cho tôi biết! (MatplotLib, OpenCV, vv)

Trả lời

12

Nếu bạn muốn gắn bó với cách tiếp cận đường viền, bạn có thể chỉ cần thêm đối số cấp độ với giá trị 'làm tròn' hình ảnh giữa nền trắng và lá.

Bạn có thể sử dụng biểu đồ để tìm giá trị phù hợp. Nhưng trong trường hợp này, bất kỳ giá trị nào hơi thấp hơn 255 sẽ làm.

Vì vậy:

contour(im, levels=[245], colors='black', origin='image') 

enter image description here

Hãy chắc chắn rằng bạn kiểm Scikit-Image nếu bạn muốn làm một số xử lý hình ảnh nghiêm trọng. Nó chứa một số các thuật toán phát hiện cạnh, vv

http://scikit-image.org/docs/dev/auto_examples/

+0

Câu trả lời hay! Và cảm ơn lời khuyên của bạn về Scikit-Image, tôi sẽ xem nó! – Xithias

0

tôi sẽ recommand sử dụng OpenCV cho hiệu suất. Nó có chức năng findContour có thể truy cập từ trăn bằng cách sử dụng liên kết cv2. Chức năng này có thể được thiết lập để chỉ trả lại đường bao ngoài.

Bạn cũng sẽ phải ngưỡng hình ảnh của mình.

+0

Bạn có thể đăng mã để trích xuất đường bao ngoài bằng cách sử dụng OpenCV không? – Xithias

+0

Tôi sắp trả lời bạn. Quá muộn nó có vẻ! –

4

Đối với những người muốn giải pháp OpenCV, ở đây nó là:

ret,thresh = cv2.threshold(image,245,255,0) 
contours, hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_NONE) 

tam = 0 

for contorno in contours: 
    if len(contorno) > tam: 
     contornoGrande = contorno 
     tam = len(contorno) 

cv2.drawContours(image,contornoGrande.astype('int'),-1,(0,255,0),2) 

cv2.imshow('My image',image) 

cv2.waitKey() 
cv2.destroyAllWindows() 

Trong ví dụ này, tôi chỉ vẽ đường viền lớn nhất. Hãy nhớ rằng 'hình ảnh' phải là một mảng kênh đơn.

Bạn nên thay đổi các thông số của hàm ngưỡng, hàm findContours và hàm drawContours để có được những gì bạn muốn.

tôi làm việc chuyển đổi để 'int' trong drawContours chức năng vì có một lỗi trong Open CV 2.4.3 phiên bản và nếu bạn không thực hiện chuyển đổi này, chương trình sẽ bị hỏng. This is the bug.

Các vấn đề liên quan