در این پست یک راه حل نسبتا ساده برای نوشتن فارسی نویسی موقع استفاده از OpenCV رو بررسی میکنیم.
openCV چیست؟
اوپنسیوی یا همان Open Computer Vision Library مجموعه ای از کتابخانههای برنامهنویسی پردازش تصویر و یادگیری ماشین است. این مجموعه بیشتر بر پردازش تصویر بی درنگ تمرکز دارد. در ابتدا توسط اینتل ساخته و پشتیبانی میشد و هماکنون توسط Willow Garage و Itseez پشتیبانی میگردد.
ویکی پدیا ویدیوی این مطلب:
لینک یوتوب آموزش نوشتن متن فارسی روی عکس در پایتون - همه مواردی که باید بدونید
نوشتن متن در openCV
قبل از اینکه مستقیم بریم وارد مشکل بشیم اول نحوه اضافه کردن یک متن انگلیسی رو به تصویر بریم و بررسی کنیم:
با استفاده از این تیکه کد میتونیم Hi There رو به تصویرمون اضافه میکنیم مثل اینجا میشه خروجی:
حالا بیاییم و متن رو تبدیل کنیم به «سلام» یعنی فقط یک خط رو ادیت کنیم نسبت به کد قبلی
image = cv2.putText(img, ‘سلام’, org, font, fontScale, color, thickness, cv2.LINE_AA)
حالا انتظار داریم که چاپ بشه به سادگی ولی نتیجه …
حالا مشکل از کجاست؟
متاسفانه برای من هم قابل باور نیستش ولی به نظر مشکل از اینه هستش:
حالا یک چیز مهم تر ASCII چیه؟ no-ascii چیه؟ UTF-8 چیه؟
واقعیتش اینجا نمیخوام براتون تمام مواردش رو بگم, به صورت خلاصه در گذشته با توجه به اینکه حافظه کامپیوتر ها محدود بودش و در ابتدا زبان انگلیسی تنها زبان استفاده کنندگان بودش کمتیه ای تصمیم گرفت که ۷ بیت که میتونه ۱۲۸ حالت رو تشکیل بده برای هر کارکتر در نظر بگیره.
یعنی کارکتر های اصلی کامپیوتر + الفبای انگلیسی کوچیک + الفبای انگلیسی بزرگ شدن شامل این مورد.
یکم عجیب باشه که باید بگم این استاندارد برمیگرده به ۱۹۶۰ میلادی ولی حالا و اینجا چرا این استاندارد برای ما مشکل ایجاد میکنه؟ خب با گذشت زمان و نبودن همچین مشکل حافظه ای و از طرفی پیشرفت کامپیوتر ها باعث شد که استفاده کنندگان با زبان های مختلفی اضافه بشن که ۱۲۸ حالت جوابگوی اونها نبودش.
UTF-8 به چه کارمون میادش؟
UTF-8 یکی از روش های کدگذاری که وجود داره UTF-8 است که در این روش ما 1,112,064 کارکتر یکتا میتونیم داشته باشیم که ۱۲۸ تای اول اون شبیه ASCII هست.
عدد 1,112,064 به اندازه ای هستش که بتونیم همه زبان های اصلی رو پوشش بدیم و همین الان شما دارید این صفحه رو با استاندارد UTF-8 میبنید و هر صفحه فارسی دیگری رو میرید, حالا بریم به بخش راه حل.
راه حل فارسی نویسی در OpenCV
در حال حاضر من این روش رو میدونم که ممکنه بهترین روش ممکنه نباشه ولی کاراست, اگر روش دیگری میشناسید حتما توی بخش کامنت ها بنویسید.
راه حل من به صورت خلاصه این هستش که بیاییم از PIL (کتابخونه پایتونی) استفاده کنیم برای این کار چون مستقیما هیچ راهی نیستش برای این کار (متاسفانه!)
اگر که این کتابخونه رو ندارید با استفاده از
pip install Pillow
نصب کنید
حالا اولین قدم بریم کدمون رو بررسی کنیم:
خب همه چیز به نظر اوکی هستش حتی فونت وزیر هم فراخوانی کردیم و تموم شد و رفت پس بریم نتیجه رو ببینیم.
نتیجه:
یک فرقی کرده درسته؟ قبلا نمیدونستیم چی چی رو داره چاپ میکنه الان دو مشکل داره
۱. از چپ به راست هست
۲. حروف الفبا از هم جدا هستن
مثلا سلام شده «مالس»
اگر میخواستیم چینی بنویسیم مشکلمون اینجا تموم میشدش مثلا “端午节就要到了”
چون چینی از چپ به راست هستش و فاصله بین حروفش هم مشکلی نیستش, خب بریم این مشکل رو حل کنیم که متن تر و تمیز فارسی داشته باشیم.
فارسی و راست چین نویسی روی تصاویر پایتون
ابتدا باید دو کتابخونه رو نصب کنیم
- arabic_reshaper
- python-bidi
با استفاده از pip
حالا بریم رویه رو ببینیم
نسبت به قبل دو خط کد جدا از فراخوانی کتابخونه ها اضافه کردم و یک متغییر رو تغییر دادم
اول نتیجه رو ببینیم که این همه منتظر بودیم:
ابتدا خط
این خط از حالت فعلی تبدیل میکند به حالت مناسب که از لحاظ دیداری فرق زیادی ندارد
‘ﺳﻼﻡ ﻣﻦ ﺍﻣﯿﻦ ﻫﺴﺘﻢ ﻭ ﺍﯾﻦ ﯾﮏ ﻣﺘﻦ ﻓﺎﺭﺳﯿﺖ.’
این خروجی متغییر reshaped_text میباشد حالا در خط بعدی
تبدیل میکنیم به حالتی که نیم فاصله ها رو درست نشون بده که اگر متغیر bidi_text رو چاپ کنیم این رو برامون نشون میده:
‘.ﺖﯿﺳﺭﺎﻓ ﻦﺘﻣ ﮏﯾ ﻦﯾﺍ ﻭ ﻢﺘﺴﻫ ﻦﯿﻣﺍ ﻦﻣ ﻡﻼﺳ’
و این رو میدیم به تابع draw.text تا برای ما بکشدش
حالا قدم بعد تر اگر بخواهیم از تصویر مذکور توی opencv استفاده کنیم میتونیم اون رو به این طریق بفرستیم به opencv
ابتدا نیاز به ماژول cv2 و numpy دارید
اینم هم نتیجه نهایی توی یک پنجره OpenCV
منابع:
How to draw Chinese text on the image using `cv2.putText`correctly? (Python+OpenCV)
Python PIL | ImageFont.truetype()
آشنایی با کدهای اسکی (ASCII) — به زبان ساده How to write RTL(Arabic/Persian) text on images in python.