2012-04-05 15 views
22

मैं आकार में 200x200 तत्वों की एक संख्यात्मक सरणी उत्पन्न करना चाहता हूं और इसे 100,100 निर्देशांक, त्रिज्या 80 और 3 पिक्सेल की स्ट्रोक चौड़ाई में केंद्रित एक सर्कल डालना चाहता हूं। फ़ाइल ऑपरेशन को शामिल किए बिना पायथन 2.7 में इसे कैसे करें? संभावित रूप से अन्य आकारों के सामान्यीकरण की अनुमति देने के लिए ज्यामिति या इमेजिंग पुस्तकालयों का उपयोग करना।numpy arrays में सरल ज्यामितीय आकार कैसे लिखें

उत्तर

17

Cairo एक आधुनिक, लचीला और तेजी से 2 डी ग्राफिक्स पुस्तकालय है। यह Python bindings है और "सतहों" NumPy सरणी के आधार पर बनाने की अनुमति देता है:

import numpy 
import cairo 
import math 
data = numpy.zeros((200, 200, 4), dtype=numpy.uint8) 
surface = cairo.ImageSurface.create_for_data(
    data, cairo.FORMAT_ARGB32, 200, 200) 
cr = cairo.Context(surface) 

# fill with solid white 
cr.set_source_rgb(1.0, 1.0, 1.0) 
cr.paint() 

# draw red circle 
cr.arc(100, 100, 80, 0, 2*math.pi) 
cr.set_line_width(3) 
cr.set_source_rgb(1.0, 0.0, 0.0) 
cr.stroke() 

# write output 
print data[38:48, 38:48, 0] 
surface.write_to_png("circle.png") 

इस कोड को प्रिंट

[[255 255 255 255 255 255 255 255 132 1] 
[255 255 255 255 255 255 252 101 0 0] 
[255 255 255 255 255 251 89 0 0 0] 
[255 255 255 255 249 80 0 0 0 97] 
[255 255 255 246 70 0 0 0 116 254] 
[255 255 249 75 0 0 0 126 255 255] 
[255 252 85 0 0 0 128 255 255 255] 
[255 103 0 0 0 118 255 255 255 255] 
[135 0 0 0 111 255 255 255 255 255] 
[ 1 0 0 97 254 255 255 255 255 255]] 

चक्र के कुछ यादृच्छिक टुकड़ा दिखा। यह भी इस पीएनजी बनाता है:

Red circle

+0

अद्यतन के लिए धन्यवाद क्योंकि मैं ग्रेस्केल (8 बिट) डेटा के साथ काम कर रहा हूं। मैं निम्नलिखित का उपयोग कर रहा हूं: \ डेटा = numpy.zeros ((200, 200), dtype = numpy.uint8) \ सतह = cairo.ImageSurface.create_for_data (डेटा, cairo.FORMAT_A8, 200, 200) \ #to 50% ग्रे सतह पेंट करें (अल्फा मान का उपयोग किया जाता है) \ cr.set_source_rgba (0, 0, 0, 0.5) – a1an

+0

यदि कोई इस उदाहरण का उपयोग कैरोक्फी लाइब्रेरी के साथ करने का प्रयास कर रहा है, तो यह काम नहीं करेगा। कैरोक्फी रेपो पर एक मुद्दा यहां दिया गया है जो अधिक विस्तार से जाता है: https: // github।कॉम/कोज़ी/कैरोक्फी/अंक/51 – neelshiv

6

opencv नया अजगर बाइंडिंग import cv2 डिफ़ॉल्ट छवि प्रारूप

रूप NumPy सरणी बनाने इनमें शामिल हैं drawing functions

+0

उत्पादन सरणियों क्या प्रारूप होता है? निर्देशांक या बाइनरी ग्रिड की बस एक सूची? –

+0

यह एक छवि = यानी आमतौर पर एक 2 डी numpy सरणी है, आप उन पर सभी सामान्य numpy संचालन कर सकते हैं और किसी भी छवि प्रारूप –

+0

ग्रेट में सहेज सकते हैं, अद्यतन @Martin –

31

हमेशा की तरह एक जाल समन्वय और अपने आकार के समीकरण लागू परिभाषित करने के लिए है। कि सबसे आसान तरीका है numpy.mgrid उपयोग करने के लिए है करने के लिए:

http://docs.scipy.org/doc/numpy/reference/generated/numpy.mgrid.html

# xx and yy are 200x200 tables containing the x and y coordinates as values 
# mgrid is a mesh creation helper 
xx, yy = numpy.mgrid[:200, :200] 
# circles contains the squared distance to the (100, 100) point 
# we are just using the circle equation learnt at school 
circle = (xx - 100) ** 2 + (yy - 100) ** 2 
# donuts contains 1's and 0's organized in a donut shape 
# you apply 2 thresholds on circle to define the shape 
donut = numpy.logical_and(circle < (6400 + 60), circle > (6400 - 60)) 
+0

मुझे कभी नहीं पता था कि numpy ऐसा कर सकता है! –

+2

@ मार्टिनबेकेट मैग्रीड आपको मूल्यों की एक श्रृंखला पर कार्यों का मूल्यांकन करने की अनुमति देता है। ध्यान दें कि आप 2 आयाम तक सीमित नहीं हैं। – Simon

+2

एक तरफ ध्यान दें, मुझे 'donut = (सर्कल <(6400 + 60)) और (सर्कल> (6400 - 60))' स्पष्ट रूप से 'logical_and' को कॉल करने से थोड़ा अधिक पठनीय लगता है। हालांकि, यह व्यक्तिगत वरीयता का मामला है। वे बिल्कुल बराबर हैं। (ध्यान दें कि '& '' numpy.logical_and' को कॉल करेगा, जबकि 'और' को ओवरराइड नहीं किया जा सकता है।) –

2

एक और संभावना scikit-image उपयोग करने के लिए है। आप एक पूर्ण सर्कल के लिए खोखले या circle के लिए circle_perimeter का उपयोग कर सकते हैं।

तुम इतनी तरह एक झटके में ही चक्र आकर्षित कर सकते हैं:

import matplotlib.pyplot as plt 
from skimage import draw 
arr = np.zeros((200, 200)) 
rr, cc = draw.circle_perimeter(100, 100, radius=80, shape=arr.shape) 
arr[rr, cc] = 1 
plt.imshow(arr) 
plt.show() 

तुम भी एक loop का उपयोग करके एक स्ट्रोक का अनुकरण कर सकते हैं। इस मामले में आप कलाकृतियों से बचने के लिए विरोधी aliased संस्करण का उपयोग करना चाहिए:

import matplotlib.pyplot as plt 
from skimage import draw 
arr = np.zeros((200, 200)) 
stroke = 3 
# Create an outer and inner circle. Then subtract the inner from the outer. 
radius = 80 
inner_radius = radius - (stroke // 2) + (stroke % 2) - 1 
outer_radius = radius + ((stroke + 1) // 2) 
ri, ci = draw.circle(100, 100, radius=inner_radius, shape=arr.shape) 
ro, co = draw.circle(100, 100, radius=outer_radius, shape=arr.shape) 
arr[ro, co] = 1 
arr[ri, ci] = 0 
plt.imshow(arr) 
plt.show() 
:

import matplotlib.pyplot as plt 
from skimage import draw 
arr = np.zeros((200, 200)) 
stroke = 3 
# Create stroke-many circles centered at radius. 
for delta in range(-(stroke // 2) + (stroke % 2), (stroke + 1) // 2): 
    rr, cc, _ = draw.circle_perimeter_aa(100, 100, radius=80+delta, shape=arr.shape) 
    arr[rr, cc] = 1 
plt.imshow(arr) 
plt.show() 

एक शायद और अधिक कारगर तरीका दो पूर्ण हलकों पैदा करते हैं और बाहरी एक से "घटाना" आंतरिक करने के लिए है

दो तरीकों से वास्तव में थोड़ा अलग परिणाम मिलते हैं।

Circle with <code>stroke=3</code>

संबंधित मुद्दे