2025, Oct 23 03:31

PIL बनाम NumPy रेंडर: matplotlib में इमेज अलग क्यों दिखती और समाधान

PIL पर इमेज तेज़, NumPy array पर धुंधली क्यों? matplotlib रेंडरिंग के कारण जानें, और ImageOps.grayscale से आउटपुट EasyOCR के लिए एकसमान व स्पष्ट बनाएं.

जब आप PIL इमेज़ को सीधे matplotlib से दिखाते हैं और वही कंटेंट numpy array में बदलकर रेंडर करते हैं, तो दोनों विज़ुअल हैरानीजनक रूप से अलग दिख सकते हैं। कई बार पहला प्लॉट बहुत स्पष्ट होता है, जबकि array-आधारित दृश्य मुश्किल से पढ़ा जाता है। अगर यही इमेज EasyOCR के लिए जा रही हो, तो स्वाभाविक है कि आप तीक्ष्ण वाला संस्करण ही देना चाहेंगे।

यह सवाल क्यों उठा

मुझे जिज्ञासा है कि PIL लाइब्रेरी स्केलिंग और नॉर्मलाइज़ेशन के स्तर पर ऐसा क्या करती है कि इमेज तेज़ दिखती है, और निकाले गए numpy मानों पर सीधे matplotlib लगाने से तस्वीर इतनी खराब क्यों लगती है।

समस्या को दोहराकर देखना

साधारण-से चरणों—क्रॉप, डिस्प्ले, array में रूपांतरण, शর্ত के आधार पर रिप्लेसमेंट, और फिर से दिखाने—के साथ यह अंतर साफ दिखता है। दोनों विज़ुअलाइज़ेशन में एकमात्र फर्क यह है कि matplotlib को इनपुट के रूप में PIL इमेज मिल रही है या numpy array.

from PIL import Image
import numpy as np
import matplotlib.pyplot as plt
img_handle = Image.open(tmp_img_path)
crop_roi = img_handle.crop((520, 965, 565, 1900))
plt.imshow(crop_roi, cmap='gray')
plt.show()
arr_view = np.array(crop_roi, dtype=np.uint8)
arr_view[np.where(arr_view == 48)] = 255
plt.imshow(arr_view, cmap='gray')
plt.show()

असल में हो क्या रहा है

सीधे PIL इमेज दिखाने पर नतीजा तीक्ष्ण दिखता है, लेकिन array-आधारित दृश्य वैसा नहीं होता। इस स्थिति में कारगर उपाय है कि अगले कदमों से पहले क्रॉप की गई इमेज को स्पष्ट तौर पर ग्रेस्केल में बदल दें। यह रूपांतरण डेटा को इस तरह संरेखित करता है कि numpy array के रूप में दिखाने पर भी आउटपुट साफ आता है।

समाधान

PIL इमेज पर ग्रेस्केल रूपांतरण लागू करने से array रेंडरिंग भी सीधे डिस्प्ले जितनी स्पष्ट दिखती है।

from PIL import Image, ImageOps
import numpy as np
import matplotlib.pyplot as plt
img_handle = Image.open(tmp_img_path)
crop_roi = img_handle.crop((520, 965, 565, 1900))
crop_roi = ImageOps.grayscale(crop_roi)
plt.imshow(crop_roi, cmap='gray')
plt.show()
arr_view = np.array(crop_roi, dtype=np.uint8)
arr_view[np.where(arr_view == 48)] = 255
plt.imshow(arr_view, cmap='gray')
plt.show()

यह क्यों मायने रखता है

EasyOCR जैसे OCR वर्कफ़्लो में छोटे-छोटे दृश्य अंतर भी सटीकता पर बड़ा असर डाल सकते हैं। अगर अंततः आप मॉडल को numpy वाला दृश्य ही देते हैं, तो आप चाहेंगे कि वह प्रस्तुति उतनी ही साफ और सुसंगत हो जितनी प्रीव्यू में दिखती है। array में बदलने से पहले ग्रेस्केल रूपांतरण सुनिश्चित करने से स्क्रीन पर दिख रहे परिणाम और मॉडल को मिलने वाले इनपुट के बीच असंगति नहीं रहती।

निष्कर्ष

अगर सीधे दिखाने पर PIL इमेज साफ दिखती है लेकिन numpy array दृश्य पढ़ना कठिन हो जाता है, तो डिस्प्ले या array रूपांतरण से पहले ImageOps.grayscale से इमेज को ग्रेस्केल में बदल दें। यह छोटा-सा कदम आउटपुट को एकसमान करता है और वही भरोसेमंद प्रीव्यू देता है जिसे आगे का कोड—EasyOCR सहित—वास्तव में प्रोसेस करेगा।

यह लेख StackOverflow पर प्रश्न (लेखक: El Dude) और El Dude के उत्तर पर आधारित है।