آموزش پایتون OpenCV-بینایی رایانه ای با OpenCV در پایتون

آموزش پایتون OpenCV-بینایی رایانه ای با OpenCV در پایتون

OpenCV آموزش - Edureka

در این مقاله آموزشی OpenCV Python ، ما جنبه های مختلف دید کامپیوتر را با استفاده از OpenCV در پایتون پوشش خواهیم داد. OpenCV برای مدت طولانی بخشی حیاتی در توسعه نرم افزار بوده است. یادگیری OpenCV یک سرمایه خوب برای توسعه دهنده برای بهبود جنبه های برنامه نویسی است و همچنین در ایجاد حرفه توسعه نرم افزار کمک می کند.

ما مفاهیم زیر را بررسی می کنیم:

کامپیوتر چیست بینایی؟ رایانه چگونه تصویر را می خواند؟ OpenCV چیست؟ مبانی OpenCV تشخیص تصویر با استفاده از OpenCV آشکارساز حرکت با استفاده از OpenCV

چشم انداز رایانه ای چیست؟

برای ساده سازی پاسخ به این مورد - اجازه دهید سناریویی را در نظر بگیریم.

همه ما از فیس بوک استفاده کنید ، درست است؟ بگذارید بگوییم شما و دوستانتان به تعطیلات رفته اید و شما روی تعداد زیادی عکس کلیک کرده اید و می خواهید آنها را در فیس بوک بارگذاری کنید و این کار را انجام داده اید. اما حالا ، آیا پیدا کردن چهره دوستان و برچسب گذاری آنها در تک تک عکس ها اینقدر زمان نمی برد؟ خوب ، فیس بوک به اندازه کافی هوشمند است تا افراد را برای شما تگ کند.

بنابراین ، فکر می کنید ویژگی برچسب خودکار چگونه کار می کند؟ به زبان ساده ، روی بینایی رایانه کار می کند.

بینایی کامپیوتری یک حوزه بین رشته ای است که به نحوه ایجاد رایانه برای درک سطح بالا از تصاویر یا فیلم های دیجیتالی می پردازد.

ایده در اینجا این است که وظایفی را که سیستم های بصری انسان می توانند انجام دهند ، خودکار کند. بنابراین ، یک کامپیوتر باید بتواند اشیایی مانند صورت یک انسان یا چراغ چراغ یا حتی یک مجسمه را تشخیص دهد.

چگونه یک کامپیوتر یک تصویر را می خواند؟

تصویر زیر را در نظر بگیرید:

ما می توانیم بفهمیم این تصویری از خط افق نیویورک است. اما آیا یک کامپیوتر می تواند همه اینها را به تنهایی پیدا کند؟ پاسخ منفی است!

رایانه هر تصویری را در محدوده مقادیر بین 0 تا 255 می خواند.

برای هر تصویر رنگی ، 3 کانال اصلی وجود دارد - قرمز ، سبز و آبی به نحوه عملکرد آن بسیار ساده است.

برای هر رنگ اصلی یک ماتریس تشکیل می شود و بعداً این ماتریس ها ترکیب می شوند و مقدار Pixel را برای رنگهای R ، G ، B ارائه می کنند.

هر کدام عنصر ماتریس داده های مربوط به شدت روشنایی پیکسل را ارائه می دهد.

تصویر زیر را در نظر بگیرید:

همانطور که نشان داده شده است ، اندازه تصویر در اینجا می تواند B*A x 3 محاسبه شود.

توجه: برای یک تصویر سیاه و سفید ، فقط یک کانال واحد وجود دارد.

در ادامه این مقاله ، بیایید ببینیم که OpenCV در واقع چیست.

OpenCV چیست؟

< p> OpenCV یک کتابخانه پایتون است که برای حل مشکلات بینایی کامپیوتر طراحی شده است. OpenCV در ابتدا در سال 1999 توسط اینتل توسعه یافت اما بعداً توسط Willow Garage پشتیبانی شد.

OpenCV از طیف گسترده ای از زبان های برنامه نویسی مانند C ++ ، Python ، Java و غیره پشتیبانی می کند. و MacOS.

OpenCV پایتون چیزی نیست جز یک کلاس بسته بندی برای کتابخانه اصلی C ++ که با پایتون استفاده می شود. با استفاده از این ، همه ساختارهای آرایه OpenCV به/از آرایه های NumPy تبدیل می شوند.

این امر ادغام آن با سایر کتابخانه هایی که از NumPy استفاده می کنند را آسان می کند. برایبه عنوان مثال ، کتابخانه هایی مانند SciPy و Matplotlib.

در ادامه این مقاله ، اجازه دهید برخی از عملیات اساسی را که می توانیم با OpenCV انجام دهیم ، بررسی کنیم.

عملیات اساسی با OpenCV؟ < /h1>

اجازه دهید مفاهیم مختلفی را از بارگذاری تصاویر گرفته تا تغییر اندازه آنها و غیره بررسی کنیم.

بارگیری یک تصویر با استفاده از OpenCV:

 وارد کردن cv2
# تصویر رنگی
Img = cv2.imread ("Penguins.jpg" ، 1)
# سیاه و سفید (مقیاس خاکستری)
Img_1 = cv2.imread ("Penguins.jpg" ، 0)) 

همانطور که در قطعه کد بالا مشاهده شد ، اولین نیاز وارد کردن ماژول OpenCV است.

بعداً ما می تواند تصویر را با استفاده از ماژول imread بخواند. 1 در پارامترها نشان می دهد که یک تصویر رنگی است. اگر پارامتر به جای 1 ، 0 باشد ، به این معنی است که تصویر وارد شده یک تصویر سیاه و سفید است. نام تصویر در اینجا "پنگوئن ها" است. کاملاً ساده ، درست است؟

شکل تصویر/وضوح تصویر:

ما می توانیم از تابع فرعی شکل برای چاپ شکل تصویر استفاده کنیم. به زیر مراجعه کنید.

 وارد کردن cv2
# سیاه و سفید (مقیاس خاکستری)
Img = cv2.imread ("Penguins.jpg"، 0)
Print (img.shape) 

منظور از شکل تصویر ، شکل آرایه NumPy است. همانطور که در اجرای کد مشاهده می کنید ، ماتریس شامل 768 ردیف و 1024 ستون است.

نمایش تصویر:

نمایش تصویر با استفاده از OpenCV بسیار ساده و سرراست است. به زیر مراجعه کنید.

 وارد کردن cv2
# سیاه و سفید (مقیاس خاکستری)
Img = cv2.imread ("Penguins.jpg"، 0)
cv2.imshow ("پنگوئن ها" ، img)
cv2.waitKey (0)
# cv2.waitKey (2000)
cv2.destroyAllWindows () 

همانطور که مشاهده می کنید ، ابتدا تصویر را با استفاده از imread وارد می کنیم. ما برای نمایش تصاویر به یک خروجی پنجره نیاز داریم ، درست است؟

ما از تابع imshow برای نمایش تصویر با باز کردن یک پنجره استفاده می کنیم. 2 پارامتر برای تابع imshow وجود دارد که نام پنجره و تصویر مورد نظر است.

بعداً منتظر یک رویداد کاربر هستیم. waitKey تا زمانی که کاربر کلیدی را فشار ندهد پنجره را ثابت می کند. پارامتری که به آن منتقل می شود زمان بر حسب میلی ثانیه است.

و در نهایت ، ما از killAllWindows برای بستن پنجره بر اساس پارامتر waitForKey استفاده می کنیم.

تغییر اندازه تصویر:

< p> به طور مشابه ، تغییر اندازه تصویر بسیار آسان است. در اینجا قطعه کد دیگری وجود دارد:

 وارد کردن cv2
# سیاه و سفید (مقیاس خاکستری)
img = cv2.imread ("Penguins.jpg"، 0)
resized_image = cv2.resize (img، (650،500))
cv2.imshow ("پنگوئن ها" ، resized_image)
cv2.waitKey (0)
cv2.destroyAllWindows () 

در اینجا از تابع تغییر اندازه برای تغییر اندازه تصویر به شکل دلخواه استفاده می شود. پارامتر اینجا شکل تصویر تغییر اندازه جدید است.

بعداً توجه داشته باشید که شیء تصویر از img به resized_image تغییر می کند ، زیرا شیء تصویر در حال حاضر تغییر کرده است.

بقیه کد برای کد قبلی بسیار ساده است ، درست است؟

من مطمئن هستم که شما کنجکاو هستید که به پنگوئن ها نگاه کنید ، درست است؟ این تصویری است که ما در تمام این مدت به دنبال خروجی آن بودیم!

روش دیگری برای انتقال پارامترها به تابع تغییر اندازه وجود دارد. به پایین مراجعه کنید.

 Resized_image = cv2.resize (img، int (img.shape [1]/2)، int (img.shape [0]/2))) 

در اینجا ، شکل تصویر جدید نصف تصویر اصلی می شود.

در ادامه این مقاله ، اجازه دهید نحوه تشخیص چهره با استفاده از OpenCV را بررسی کنیم.

تشخیص چهره با استفاده از OpenCV

این روش در ابتدا پیچیده به نظر می رسد اما بسیار آسان است. اجازه دهید کل مراحل را با شما در میان بگذارم و شما نیز همان احساس را خواهید داشت.

مرحله 1: با توجه به پیش نیازهای ما ، برای شروع به تصویر نیاز داریم. بعداً ما باید یک طبقه بندی آبشار ایجاد کنیم کهدر نهایت ویژگی های چهره را به ما می دهد.

مرحله 2: این مرحله شامل استفاده از OpenCV است که تصویر و فایل ویژگی ها را می خواند. بنابراین در این مرحله ، آرایه های NumPy در نقاط اصلی داده وجود دارد.

تنها کاری که باید انجام دهیم این است که مقادیر سطر و ستون صورت NumPy ndarray را جستجو کنیم. این آرایه با مختصات مستطیل صورت است.

مرحله 3: این مرحله نهایی شامل نمایش تصویر با کادر صورت مستطیلی است.

تصویر زیر را بررسی کنید ، در اینجا من خلاصه کرده ام 3 مرحله به شکل تصویر برای خوانایی راحت تر:

بسیار ساده ، درست است؟

ابتدا ، یک شی CascadeClassifier برای استخراج ویژگی های صورت ایجاد می کنیم ، همانطور که قبلاً توضیح داده شد. مسیر فایل XML که حاوی ویژگی های چهره است ، پارامتر اینجاست.

مرحله بعدی خواندن تصویری است که روی آن چهره وجود دارد و با استفاده از COLOR_BGR2GREY به تصویر سیاه و سفید تبدیل می شود. به دنبال آن ، مختصات تصویر را جستجو می کنیم. این کار با استفاده از deteMultiScale انجام می شود.

از چه مختصاتی می پرسید؟ این مختصات مستطیل صورت است. scaleFactor برای کاهش مقدار شکل تا 5٪ تا زمانی که صورت پیدا شود استفاده می شود. بنابراین ، در کل - هر چه مقدار کوچکتر باشد ، دقت بیشتر است.

در نهایت ، صورت روی پنجره چاپ می شود.

افزودن کادر صورت مستطیلی:

< p> این منطق بسیار ساده است - به سادگی استفاده از دستور حلقه for. تصویر زیر را ببینید.

ما تعریف روش ایجاد مستطیل با استفاده از cv2.rectangle با عبور پارامترهایی مانند شیء تصویر ، مقادیر RGB طرح کلی جعبه و عرض مستطیل.

اجازه دهید کل کد را برای تشخیص چهره بررسی کنیم: < /p>

 وارد کردن cv2
# یک CascadeClassifier Object ایجاد کنید
face_cascade = cv2.CascadeClassifier ("haarcascade_frontalface_default.xml")
# خواندن تصویر همانطور که هست
img = cv2.imread ("photo.jpg")
# خواندن تصویر به عنوان تصویر مقیاس خاکستری
gray_img = cv2.cvtColor (img ، cv2.COLOR_BGR2GRAY)
# مختصات تصویر را جستجو کنید
چهره ها = face_cascade.detectMultiScale (gray_img، scaleFactor = 1.05،
                                      حداقل همسایگان = 5)
برای x ، y ، w ، h در صورت:
    img = cv2. rectangle (img، (x، y)، (x+w، y+h)، (0،255،0)، 3)
تغییر اندازه = cv2.resize (img، (int (img.shape [1]/7)، int (img.shape [0]/7)))
cv2.imshow ("خاکستری" ، تغییر اندازه)
cv2.waitKey (0)
cv2.destroyAllWindows () 

در ادامه این مقاله ، بیایید نحوه استفاده از OpenCV برای ضبط ویدئو با وب کم کامپیوتر را بررسی کنیم.

ضبط ویدئو با استفاده از OpenCV

< p> فیلمبرداری با استفاده از OpenCV نیز بسیار ساده است. حلقه زیر ایده بهتری به شما می دهد. آن را بررسی کنید:

تصاویر یکی خوانده می شوند ویدئوها به دلیل پردازش سریع فریم ها ایجاد می شوند که باعث حرکت تک تک تصاویر می شود.

ضبط ویدئو:

تصویر زیر را مشاهده کنید:

< img src = "https://cdn-images-1.medium.com/max/426/1*AElOdTJjCzjfnWIhKwXcYA.png">

ابتدا کتابخانه OpenCV را طبق معمول وارد می کنیم. در مرحله بعد ، روشی به نام VideoCapture داریم که برای ایجاد شی VideoCapture استفاده می شود. این روش برای فعال کردن دوربین روی دستگاه کاربر استفاده می شود. پارامتر این عملکرد نشان می دهد که آیا برنامه باید از دوربین داخلی یا دوربین اضافی استفاده کند. "0" نشان دهنده دوربین داخلی استاین مورد.

و سرانجام ، از روش انتشار برای رهاسازی دوربین در چند میلی ثانیه استفاده می شود.

وقتی جلو می روید و تایپ می کنید و سعی می کنید کد فوق را اجرا کنید ، متوجه می شود که چراغ دوربین برای چند ثانیه روشن می شود و بعداً خاموش می شود. چرا این اتفاق می افتد؟

این اتفاق می افتد زیرا هیچ زمان تأخیری برای عملکرد دوربین وجود ندارد.

با نگاهی به کد بالا ، خط جدیدی به نام time.sleep (3) داریم - این باعث می شود که اسکریپت به مدت 3 ثانیه متوقف شود. توجه داشته باشید که پارامتر منتقل شده زمان در ثانیه است. بنابراین ، وقتی کد اجرا شد ، وب کم به مدت 3 ثانیه روشن می شود.

افزودن پنجره:

افزودن یک پنجره برای نمایش خروجی ویدئو بسیار ساده است و می تواند در مقایسه با روشهای مشابهی که برای تصاویر استفاده می شود. با این حال ، تغییر جزئی وجود دارد. کد زیر را بررسی کنید:

من زیبا هستم مطمئن باشید که می توانید از کد فوق جدا از یک یا دو خط بیشترین معنا را داشته باشید. آرایه قاب. /p>

همانطور که می توانید بررسی کنید ، خروجی را دریافت کردیم به عنوان True و بخشی از آرایه قاب چاپ می شود.

اما برای شروع باید اولین فریم/تصویر ویدیو را بخوانیم ، درست است؟

برای انجام دقیق این کار ، ما ابتدا باید یک شیء فریم ایجاد کنید که تصاویر شیء VideoCapture را بخواند.

< /img>

همانطور که در بالا مشاهده شد ، از روش imshow برای گرفتن اولین فریم ویدئو استفاده می شود.

در تمام این مدت ، ما سعی کرده ایم اولین تصویر/قاب ویدیو را به طور مستقیم ضبط کنیم ضبط ویدئو.

بنابراین چگونه می توان فیلم را به جای اولین تصویر در OpenCV ضبط کرد؟

ضبط مستقیم فیلم:

به منظور ضبط ویدیو ، ما از حلقه while استفاده خواهیم کرد. در حالی که شرایط به گونه ای است که تا زمانی که "check" درست نباشد. اگر چنین است ، Python فریم ها را نمایش می دهد.

در اینجا تصویر قطعه کد آمده است:

ما از تابع cvtColor برای تبدیل هر فریم به تصویر در مقیاس خاکستری استفاده می کنیم ، همانطور که قبلاً توضیح داده شد.

waitKey (1) اطمینان حاصل کنید که یک فریم جدید پس از هر میلی ثانیه فاصله ایجاد می کنید.

در اینجا مهم است که توجه داشته باشید که حلقه while کاملاً در حال پخش است تا به تکرار فریم ها و در نهایت نمایش فیلم کمک کند.

ماشه رویداد کاربر نیز در اینجا وجود دارد. هنگامی که کاربر کلید 'q' را فشار می دهد ، پنجره برنامه بسته می شود.

درک OpenCV بسیار آسان است ، درست است؟ من شخصاً دوست دارم که خوانایی آن چقدر خوب است و چگونه یک مبتدی می تواند کار با OpenCV را به سرعت شروع کند.

در ادامه این مقاله ، بیایید نحوه استفاده از یک مورد کاربرد جالب آشکارساز حرکت با استفاده از OpenCV را بررسی کنیم.

مورد استفاده: تشخیص حرکت با استفاده از OpenCV

بیان مشکل:

شرکتی که رفتار انسان را مطالعه می کند با شما تماس گرفته است. وظیفه ی شمااین است که به آنها یک وب کم بدهید که بتواند حرکت یا هر حرکتی را در مقابل آن تشخیص دهد. این باید یک گراف را برگرداند ، این نمودار باید شامل مدت زمانی باشد که انسان/جسم مقابل دوربین بوده است.

بنابراین ، اکنون که ما بیانیه مشکل خود را تعریف کرده ایم ، باید منطقی راه حل ایجاد کنیم تا به صورت ساختارمند به مسئله نزدیک شویم.

در نظر بگیرید نمودار زیر:

در ابتدا ، ما ذخیره می کنیم تصویر در یک قاب خاص.

مرحله بعدی شامل تبدیل تصویر به تصویر تار Gaussian است. این کار به منظور اطمینان از محاسبه تفاوت محسوس بین تصویر تار و تصویر واقعی انجام می شود.

در این مرحله ، تصویر هنوز یک شی نیست. ما یک آستانه برای حذف لکه ها مانند سایه ها و سایر صداهای موجود در تصویر تعریف می کنیم.

حاشیه های شی بعداً مشخص می شوند و همانطور که قبلاً در وبلاگ در مورد آن صحبت کردیم ، یک جعبه مستطیلی در اطراف آن اضافه می کنیم.

در نهایت ، ما زمان نمایش و خروج شی از قاب را محاسبه می کنیم.

بسیار آسان است ، درست است؟

در اینجا قطعه کد آمده است:

< img src = "https://cdn-images-1.medium.com/max/426/1*tkoLRNbYxGMYGgSHx-eZTA.png">

همین اصل در اینجا نیز رعایت می شود. ابتدا بسته را وارد می کنیم و شیء VideoCapture را ایجاد می کنیم تا از ضبط ویدئو با استفاده از وب کم اطمینان حاصل کنیم.

حلقه while از طریق فریم های جداگانه ویدیو تکرار می شود. ما قاب رنگ را به یک تصویر در مقیاس خاکستری تبدیل می کنیم و بعداً این تصویر را در مقیاس خاکستری به محو گاوس تبدیل می کنیم.

ما باید اولین تصویر/قاب ویدیو را ذخیره کنیم ، درست است؟ ما فقط از عبارت if برای این منظور استفاده می کنیم.

اکنون ، اجازه دهید کمی بیشتر در کد وارد شویم:

ما از تابع absdiff برای محاسبه تفاوت بین اولین فریم رخ داده و همه فریم های دیگر استفاده می کنیم.

تابع آستانه یک مقدار آستانه ارائه می دهد ، به طوری که مقدار اختلاف کمتر از 30 را به سیاه تبدیل می کند. اگر تفاوت بیشتر از 30 باشد ، پیکسل ها را به رنگ سفید تبدیل می کند. THRESH_BINARY برای این منظور استفاده می شود.

بعداً ، از تابع findContours برای تعیین ناحیه کانتور برای تصویر خود استفاده می کنیم. و در این مرحله نیز مرزها را اضافه می کنیم.

عملکرد contourArea ، همانطور که قبلاً توضیح داده شد ، صداها و سایه ها را حذف می کند. برای ساده تر ، فقط آن قسمت را سفید نگه می دارد ، که مساحت آن بیشتر از 1000 پیکسل است ، همانطور که برای آن تعریف کرده ایم.

بعداً ، یک جعبه مستطیلی در اطراف شیء خود در قاب کار ایجاد می کنیم. .

و به دنبال آن این کد ساده وجود دارد:

همانطور که قبلاً بحث شد ، فریم هر 1 میلی ثانیه تغییر می کند و هنگامی که کاربر "q" را وارد می کند ، حلقه شکسته می شود و پنجره بسته می شود.

ما همه موارد اصلی را پوشش داده ایم. جزئیات این وبلاگ آموزش OpenCV Python. موردی که در مورد مورد استفاده ما باقی می ماند این است که ما باید زمانی را که شیء در مقابل دوربین قرار داشت محاسبه کنیم.

محاسبه زمان:

ما از DataFrame برای ذخیره مقادیر زمانی استفاده می کنیم که طی آن تشخیص و حرکت شی در فریم. اما در اینجا ، ما یک بیت پرچم داریم که به آن وضعیت می گوییم. ما از این وضعیت در استفاده می کنیمشروع ضبط صفر است زیرا شیء در ابتدا قابل مشاهده نیست.

هنگامی که شیء در شکل بالا مشخص می شود ، پرچم وضعیت را به 1 تغییر می دهیم. بسیار ساده ، درست است؟

ما قصد داریم فهرستی از وضعیت برای هر فریم اسکن شده تهیه کنید و بعداً تاریخ و زمان را با استفاده از زمان داده در یک لیست در صورت تغییر و مکان ایجاد کنید.

و مقادیر زمان را در یک DataFrame ذخیره می کنیم ، همانطور که در نمودار توضیحی بالا نشان داده شده است. ما با نوشتن DataFrame در یک فایل CSV مطابق شکل به پایان می رسانیم.

رسم نمودار تشخیص حرکت:

آخرین مرحله در مورد استفاده ما برای نمایش نتایج. ما نمودار را نشان می دهیم که حرکت را در 2 محور نشان می دهد. کد زیر را در نظر بگیرید:

برای شروع ، ما DataFrame را از فایل motion_detector.py وارد می کنیم.

مرحله بعدی شامل تبدیل زمان به فرمت رشته قابل خواندن است که قابل تجزیه است.

در نهایت ، مقادیر زمانی DataFrame رسم می شود در مرورگر با استفاده از نمودارهای بوکه.

خروجی:

امیدوارم این مقاله به شما در یادگیری تمام اصول اولیه مورد نیاز برای شروع کار با OpenCV با استفاده از پایتون کمک کند.

هنگامی که می خواهید برنامه هایی را توسعه دهید که نیاز به تشخیص تصویر دارند ، بسیار مفید خواهد بود. و اصول مشابه در حال حاضر ، شما همچنین باید بتوانید از این مفاهیم برای توسعه برنامه ها به راحتی با کمک OpenCV در پایتون استفاده کنید.

اگر مایل هستید مقالات بیشتری را در مورد پرطرفدارترین فناوری های بازار مانند هوش مصنوعی ، DevOps ، بررسی کنید. سپس می توانید به سایت رسمی Edureka مراجعه کنید.

به دنبال مقالات دیگر این سری باشید که جنبه های مختلف دیگر پایتون و علم داده را توضیح می دهد.

1. آموزش پایتون 2. زبان برنامه نویسی پایتون 3. توابع پایتون 4. مدیریت فایل در پایتون 5. آموزش پایتون Numpy 6. Scikit Learn Machine Learning 7. آموزش پایتان پایتون 8. آموزش Matplotlib 9. آموزش Tkinter 10. آموزش درخواست 11. آموزش PyGame 12. تراشیدن وب با پایتون 13. آموزش PyCharm 14. آموزش یادگیری ماشین 15. الگوریتم رگرسیون خطی از ابتدا در پایتون 16. پایتون برای علم داده 17. پایتون Regex 18. حلقه ها در Python 19. پروژه های پایتون 20. پروژه های یادگیری ماشین 21. آرایه ها در پایتون 22. مجموعه در پایتون 23. چند رشته ای در پایتون 24. سوالات مصاحبه پایتون 25. جاوا در مقابل پایتون 26. چگونه می توان توسعه دهنده پایتون شد؟ 27. توابع پایتون لامبدا 28. Netflix چگونه از پایتون استفاده می کند؟ 29. برنامه نویسی سوکت در پایتون 30 چیست. اتصال پایگاه داده پایتون 31. گلانگ در مقابل پایتون 32. آموزش Python Seaborn 33. فرصتهای شغلی پایتون

در ابتدا در www.edureka.co در 8 فوریه 2019 منتشر شد.

نظرات 0 + ارسال نظر
برای نمایش آواتار خود در این وبلاگ در سایت Gravatar.com ثبت نام کنید. (راهنما)
ایمیل شما بعد از ثبت نمایش داده نخواهد شد