मैं पाई के साथ ब्रह्मांड के द्रव्यमान और समुद्र के स्तर पर पृथ्वी के गुरुत्वाकर्षण स्थिरांक को बाइनरी में परिवर्तित करने के आधार पर एक पेंटिंग बनाने का प्रयास कर रहा हूं। मैंने गणित किया है और मेरे पास सही आयाम हैं और यह केवल एक मेगाबाइट रैम से कम होना चाहिए, लेकिन अधिकतम अनुमत आयाम मूल्य त्रुटि से अधिक चल रहा है।

यहाँ कोड है:

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

boshi = 123456789098765432135790864234579086542098765432135321 # universal mass

genesis = boshi ** 31467 # padding

artifice = np.binary_repr(genesis) # formatting

A = int(artifice) 

D = np.array(A).reshape(A, (1348, 4117))

plt.imsave('hello_world.png', D, cmap=cm.gray) # save image

मैं D = np.array... पर त्रुटि का सामना करता रहता हूं, और हो सकता है कि मेरा आकार बहुत बड़ा हो, लेकिन यह केवल 4k से थोड़ा ही बड़ा हो। ऐसा लगता है कि यह GPU एन्हांस्ड कोलाब के लिए कोई समस्या नहीं होनी चाहिए। मेरी होम मशीन पर एक ही त्रुटि के साथ नहीं चलता है। क्या यह अधिक राम के साथ तय किया जाएगा?

0
Dante Bonfatti 13 जिंदा 2019, 19:28

2 जवाब

सबसे बढ़िया उत्तर

इसे कारगर बनाना

समस्या यह है कि artifice = np.binary_repr(genesis) एक स्ट्रिंग बनाता है। स्ट्रिंग में 1348 * 4117 = 5549716 अंक होते हैं, सभी शून्य और एक। यदि आप स्ट्रिंग को एक अजगर पूर्णांक A = int(artifice) में परिवर्तित करते हैं, तो आप (ए) बहुत लंबे समय तक प्रतीक्षा करेंगे, और (बी) एक गैर-पुनरावृत्त वस्तु प्राप्त करेंगे। np.array(A) के साथ आपके द्वारा बनाई गई सरणी में एक ही तत्व होगा।

अच्छी खबर यह है कि आप इस तथ्य का उपयोग करके समय लेने वाले कदम को पूरी तरह से बायपास कर सकते हैं कि स्ट्रिंग artifice पहले से ही चलने योग्य है:

D = np.array(list(artifice), dtype=np.uint8).reshape(1348, 4117)

चरण list(artifice) में कुछ सेकंड लगेंगे क्योंकि इसे स्ट्रिंग को विभाजित करना है, लेकिन बाकी सब कुछ काफी तेज होना चाहिए।

plt.imsave('hello_world.png', D, cmap=cm.gray) के साथ वहां से प्लॉट करना आसान है:

enter image description here

कलरमैप

जब आप छवि सहेजते हैं तो आप रंग मानचित्र को आसानी से coolwarm या जो चाहें बदल सकते हैं। ध्यान रखें कि आपकी छवि द्विआधारी है, इसलिए केवल दो मान वास्तव में मायने रखेंगे:

plt.imsave('hello_world2.png', D, cmap=cm.coolwarm)

enter image description here

अन्वेषण

आपके पास अपनी छवि में बहुत सारे रंग जोड़ने का अवसर है। आम तौर पर, एक पीएनजी 8-बिट होता है। उदाहरण के लिए, genesis को बिट्स में बदलने के बजाय, आप इमेज बनाने के लिए इससे बाइट ले सकते हैं। आप 16 रंगों के साथ एक अनुक्रमित छवि बनाने के लिए निबल्स (आधा-बाइट्स) भी ले सकते हैं। थोड़ी सी पैडिंग के साथ, आप यह भी सुनिश्चित कर सकते हैं कि आपके पास तीन डेटा बिंदुओं में से एक है, और किसी भी तरह से पूर्ण रंगीन आरजीबी छवि बनाएं। मैं अधिक जटिल विकल्पों में नहीं जाऊंगा, लेकिन मैं बाइट्स से एक साधारण छवि बनाने का पता लगाना चाहूंगा।

5549716 बिट्स 693715 = 5 * 11 * 12613 बाइट्स हैं (चार प्रमुख शून्य बिट्स के साथ)। यह 55x12613 के छवि आकार के लिए एक बहुत ही बुरा कारक है, तो चलिए उस ऊपरी निबल को हटा दें: जबकि 693716 का गुणनखंड उतना ही खराब है जितना कि 693715, 693714 कारक बहुत अच्छी तरह से 597 * 1162 में।

आप अपने पूर्णांक को उसके स्वयं के to_bytes विधि:

from math import ceil

byte_genesis = genesis.to_bytes(ceil(genesis.bit_length() / 8), 'big')

मेरे द्वारा बिल्ट-इन ceil के बजाय np.ceil है कि यह एक फ्लोट के बजाय एक पूर्णांक लौटाता है।

विशाल पूर्णांक को परिवर्तित करना बहुत तेज़ है क्योंकि bytes ऑब्जेक्ट की पूर्णांक के डेटा तक सीधी पहुंच होती है: भले ही यह एक प्रतिलिपि बनाता है, यह वस्तुतः कोई प्रसंस्करण नहीं करता है। यह बफर को साझा भी कर सकता है क्योंकि bytes और int दोनों नाममात्र के अपरिवर्तनीय हैं। इसी तरह, आप np.frombuffer:

img = np.frombuffer(byte_genesis, dtype=np.uint8)[1:].reshape(597, 1162)

[1:] प्रमुख कुतरने के लिए आवश्यक है, क्योंकि bytes_genesis genesis की संपूर्णता को धारण करने के लिए पर्याप्त बड़ा होना चाहिए। आप bytes साइड से भी काट सकते हैं:

img = np.frombuffer(byte_genesis[1:], dtype=np.uint8).reshape(597, 1162)

परिणाम समान हैं। यहाँ चित्र कैसा दिखता है:

plt.imsave('hello_world3.png', img, cmap=cm.viridis)

परिणाम अपलोड करने के लिए बहुत बड़ा है (क्योंकि यह एक बाइनरी छवि नहीं है), लेकिन यहां एक यादृच्छिक रूप से चयनित नमूना है:

enter image description here

मुझे यकीन नहीं है कि यह सौंदर्य की दृष्टि से आप क्या खोज रहे हैं, लेकिन उम्मीद है कि यह आपको बहुत बड़ी संख्या को डेटा बफ़र्स में बदलने के तरीके को देखने के लिए एक जगह प्रदान करता है।

अधिक विकल्प, क्योंकि यह दिलचस्प है

मैं यहां बाइट्स के बजाय निबल्स का उपयोग करना चाहता था, क्योंकि इससे आपको प्रति पिक्सेल 16 रंग और दो बार पिक्सेल की अनुमति मिल जाएगी। आप 1162x1194 इमेज से शुरू कर सकते हैं

temp = np.frombuffer(byte_genesis, dtype=np.uint8)[1:]

निबल्स को अनपैक करने का एक तरीका यहां दिया गया है:

img = np.empty((1162, 1194), dtype=np.uint8)
img.ravel()[::2] = np.bitwise_and(temp >> 4, 0x0F)
img.ravel()[1::2] = np.bitwise_and(temp, 0x0F)

jet जैसे रंगरूप के साथ, आपको मिलता है:

plt.imsave('hello_world4.png', img, cmap=cm.jet)

enter image description here

एक अन्य विकल्प, बोलने के तरीके में विपरीत दिशा में जाना) कोलोरमैप्स का उपयोग बिल्कुल नहीं करना है। इसके बजाय, आप अपने स्थान को तीन के कारक से विभाजित कर सकते हैं और RGB स्थान में अपने स्वयं के रंग उत्पन्न कर सकते हैं। सौभाग्य से, 693714 के प्रमुख कारकों में से एक 3 है। इसलिए आपके पास 398x581 छवि (693714 == 3 * 398 * 581) हो सकती है। आप डेटा की व्याख्या कैसे करते हैं यह आपके ऊपर सामान्य से भी अधिक है।

जारी रखने से पहले साइड नोट

श्वेत-श्याम बाइनरी छवि के साथ, आप छवि के रंग, आकार और अभिविन्यास को नियंत्रित कर सकते हैं। 8-बिट डेटा के साथ, आप नियंत्रित कर सकते हैं कि बिट्स का नमूना कैसे लिया गया (8 या उससे कम, जैसा कि 4-बिट उदाहरण में है), आपकी व्याख्या की अंतहीनता, रंग नक्शा और छवि का आकार। पूर्ण रंग के साथ, आप प्रत्येक ट्रिपल को एक अलग रंग के रूप में मान सकते हैं, संपूर्ण डेटासेट को लगातार तीन रंगीन विमानों के रूप में मान सकते हैं, या यहां तक ​​कि बायर फ़िल्टर। सभी अन्य विकल्पों के अलावा आकार, क्रम, प्रति नमूना बिट्स की संख्या, आदि।

निम्नलिखित अभी के लिए रंग ट्रिपल और तीन रंग विमानों के विकल्प दिखाएगा।

पूर्ण रंगीन छवियां

लगातार 3 बाइट्स के प्रत्येक सेट को आरजीबी ट्रिपल के रूप में मानने के लिए, आप ऐसा कुछ कर सकते हैं:

img = temp.reshape(398, 581, 3)
plt.imsave('hello_world5.png', img)

ध्यान दें कि इस मामले में कोई कॉलोरमैप नहीं है।

enter image description here

डेटा को तीन रंगीन विमानों के रूप में व्याख्या करने के लिए एक अतिरिक्त कदम की आवश्यकता होती है क्योंकि plt.imsave< /a> अंतिम आयाम का आकार 3 होने की अपेक्षा करता है। np.rollaxis इसके लिए एक अच्छा टूल है:

img = np.rollaxis(temp.reshape(3, 398, 581), 0, 3)
plt.imsave('hello_world6.png', img)

enter image description here

0
Mad Physicist 16 जिंदा 2019, 04:25

मैं आपकी समस्या का पुनरुत्पादन नहीं कर सका, क्योंकि लाइन A = int(artifice) हमेशा की तरह लग गई। मैंने प्रत्येक अंक को अपने आप डालने के लिए इसे ,for लूप से बदल दिया। कोड ने तब काम किया और वांछित छवि का उत्पादन किया।

import matplotlib.pyplot as plt
import matplotlib.cm as cm
import numpy as np

boshi = 123456789098765432135790864234579086542098765432135321
genesis = boshi ** 31467
artifice = np.binary_repr(genesis)

D = np.zeros((1348, 4117), dtype=int)
for i, val in enumerate(D):
    D[i] = int(artifice[i])

plt.imsave('hello_world.png', D, cmap=cm.gray)
0
Mad Physicist 13 जिंदा 2019, 20:22