شکستن کپچا

تغییرات پروژه از تاریخ 1396/11/11 تا حالا
1. مورد

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

یکی از معمول‌ترین شکل کپچا به صورت تصویر است. در این نوع کپچا معمولا حروف و اعدادی انگلیسی به شکلی کنار هم قرار می‌گیرند و از کاربر پرسیده می‌شود که بگوید که این حروف و اعداد چیست. معمولا مسئولین این سایت‌ها فکر می‌کنند که ربات‌ها یا برنامه‌های کامپیوتری نمی‌توانند پاسخ این سؤالات را بدهند.

مواقع زیادی هم رخ می‌دهد که این کپچاها به غیر از اعصاب خوردی چیزی برای ما ندارد.

[![کپچای گلستان](https://camo.githubusercontent.com/83ca50b5588375a403f8064d6c3230db9e3bf2d1/687474703a2f2f626179616e626f782e69722f69642f343539353236393138393636323935323632363f76696577)](https://camo.githubusercontent.com/83ca50b5588375a403f8064d6c3230db9e3bf2d1/687474703a2f2f626179616e626f782e69722f69642f343539353236393138393636323935323632363f76696577)

در این پروژه ما می‌خواهیم که یک افزونه برای مروگر بنویسیم که یک کپچا را بکشند و به صورت خودکار آن را حل نماید.

برای مثال ساده‌تر می‌توانید از کپچای [سامانه آموزش دانشگاه شریف](http://edu.sharif.edu/) استفاده کنید.

[![کپچای شریف](https://camo.githubusercontent.com/5ea014cea5ddd1a2aa244ce21fe61a3effcd6e40/687474703a2f2f626179616e626f782e69722f69642f373030333934353532323732303636313236393f76696577)](https://camo.githubusercontent.com/5ea014cea5ddd1a2aa244ce21fe61a3effcd6e40/687474703a2f2f626179616e626f782e69722f69642f373030333934353532323732303636313236393f76696577)

مراحل یک سیستم برای اینکار می‌تواند بدین صورت باشد:

1.  جمع آوری یک پایگاه داده از کپچاها و تهیه پاسخ هر کدام از آن‌ها به صورت دستی
2.  جداسازی هر حرف یا عدد از هم. (یعنی یک عکس را بگیرد و چند عکس کوچکتر دیگر درست بکند که هر کدام شامل یک حرف است).
3.  استفاده از OCR یا آموزش یک دسته‌بند ساده که هر حرف را تشخصی بدهد. برای دسته بند هم می‌توان از شبکه‌های عصبی یا از SVM استفاده کرد.

# مقدمه
کپچا که انگلیسی آن بصورت CAPTCHA می باشد از سر نام جمله زیر آمده است:

**C**ompletely **A**utomated **P**ublic **T**uring Test to tell **C**omputers and **H**umans **A**part

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

1-   متداول ترین آن ها تصویری از حروف و اعداد به هم ریخته است که داری نویس هایی در پس زمینه خود هستند مانند شکل مقابل:![توضیح تصویر](https://boute.s3.amazonaws.com/270-captcha.png)

2-   -کپچاهای صوتی که شامل صدای یک سری حروف و اعداد بطور واضح می باشند اما برای خلاصی از اپلیکیشن های تشخیص صدا ممکن است صداهایی را در پشت زمینه ایجاد کند.
3-   کپچا هایی که عکس هستندو از کاربر خود میخواهند شی خاصی را در عکس تشخیص دهند بطور مثال در شکل زیر خواسته شده گربه ها تشخیص داده
شوند:  ![توضیح تصویر](https://boute.s3.amazonaws.com/270-cat.png)                          

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

**موارد استفاده کپچا:**

کپچا کاربردهای زیادی در جهت افزایش امنیت دارد که در ادامه به مهمترین آنها اشاره خواهیم کرد:

**جلوگیری از نظرات اسپم در سایت و وبلاگ**
اکثر صاحبان وبلاگ یا سایت ها با نرم افزارهای اتوماتیک آنلاین که اقدام به انتشار نظرات اسپم میکنند آشنایی دارند که معمولا به هدف افزایش رنک و بهبود سئو سایت اسپمر بکار میرود. با استفاده از کپچا تنها انسان ها قادر به انتشار نظر در بخش وبلاگ سایت شما خواهند بود و به این ترتیب نیاز به عضویت در سایت یا وبلاگ شما برای جلوگیری از نظرات اسپم نیست.

نقش کپچا در بخش عضویت سایت       
سایت های زیادی در دنیا خدمات رایگان ارائه میدهند که نیازمند عضویت و ساخت اکانت از طرف افراد هستند. مهمترین آنها سیستم های ایمیل یاهو و گوگل هستند. تا چند سال پیش و قبل از بکارگیری کپچا بزرگترین مشکل آنها ساخت تعداد زیادی اکانت توسط روبات های اینترنتی بود که میتوانستند در چند دقیقه صدها ایمیل بسازند. استفاده از سیستم کپچا این امکان را فراهم کرد که تنها انسان ها قادر به تکمیل فرم و ثبت نام نهایی باشند و امروزه به یک ضرورت در سیستم های رایگان تبدیل شده است.

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

با تمام فوایدی که برای کپچا ذکر شده است که البته محدود به موارد ذکر شده نمی باشد و قابلیت های بسیار دیگری نیز دارد نباید از این موضوع غافل شد که طراحی کپچا های سخت بطوریکه که برای انسان نیز وقت گیر باشد باعث کاهش ارتباط کاربران با سایت شما می شود.

آیا می توان راه بهتری جایگزین کپچا نمود؟؟؟
**-کپچافا:**
کپچافا یک کپچای فارسی می باشد که بجای وارد کردن حروف بی معنی لاتین می توان از کلمات معنی دار فارسی با حداقل کجی و ناواضحی استفاده کرده است.
استفاده از این نوع کپچا را به توسعه دهندگان وب فارسی پیشنهاد میشود زیرا:
– تکنولوژی بازشناسی خودکار متون برای زبان لاتین بسیار پیشرفته است به صورتی که در حال حاضر ربات‌ هایی وجود دارند که بر اساس الگوریتم‌ های پردازش تصویر و شناسایی الگو می‌توانند بسیاری از کپچا‌ها را تشخیص دهند. نمونه ‌هایی از عملکرد این ربات ‌ها را می‌ توان روزانه در بخش نظرات سایت‌ های پر مخاطب و قدرتمندی‌ مثل یاهو نیز مشاهده کرد. علاوه بر ساختار زبان و لغات فارسی که امکان ایجاد کپچافا‌های پیچیده‌ تری را نسبت به زبان لاتین ایجاد می ‌کند، تکنولوژی بازشناسی خودکار متن ها نیز در بستر زبان فارسی بسیار ضعیف و نوپا است.
–  این سرویس کاملا رایگان بوده و کاربران می ‌توانند بدون اینکه هیچ هزینه ‌ای پرداخت کنند سایت، وبلاگ و یا پورتال خود را ایمن کنند.
– برخلاف کپچا که به دلیل حملات ربات‌های اینترنتی‌ مبتنی‌ بر دیکشنری، مجبور می‌ شود که همیشه از لغات بی‌ معنی‌ استفاده کند، در کپچافا با تکیه‌ بر سطح بالای امنیت ارائه شده، می ‌توان از لغات معنی‌ دار فارسی استفاده کرد. چون خطراتی که کپچا را تهدید می ‌کنند در حال حاضر برای کپچافا وجود ندارند. نکته قابل توجهی که این ویژگی‌ خاص کپچافا دارد راحتی‌ و آسان خواندن کپچافا برای کاربر است. چرا که حتی با وجود ایجاد کجی‌ ها و نا واضحی‌ ها، انسان هوشمند با توجه به دایره لغاتی که در ذهن دارد می ‌تواند به راحتی‌ کپچافا را تشخیص دهد. در نتیجه، وضعیت آزار دهنده ‌ای که  کاربران برای خواندن کپچا‌ها دارند در مورد کپچافا پیش نمی آید.
– چهارمین دلیل که بر اساس آن تیم فنی کپچافا کاربران را تشویق می‌ کند تا از کپچافا استفاده کنند پاس داشتن ادبیات و زبان خودمان است.[5]

# کارهای مرتبط
در بخش مقدمه انواع کپچا ها معرفی شد که همه ی نوع کپچا ها را در بر نمیگرفت اما پر استفاده ترین انها را مد نظر قرار داده بودیم در این بخش قصد داریم به کار هایی که گروه های مختلف در زمینه شکستن کپچاهای صوتی و ریکپچا ها با استفاده از هوش مصنوعی انجام داده اند بپردازیم و روند کلی حل مسئله درک کنیم.
**شکستن کپچاهای صوتی**
				کپچاها ی صوتی  که سری از حروف و اعداد را بیان میکنند و کاربر باید آن را تشخیص دهد و چون ربات ها با استفاده از  اپلیکیشن های تشخیص صدا می توانند به راحتی این نوع از کپچا ها را شکست دهند در پس زمینه این کپچاها صداهای اضافی مانند نویز و موزیک نیز پخش می شود تا شکستن آن برای ربات ها کار آسانی نباشد.
				قدم اول در حل این مسئله استخراج ویژگی های هر صوت می باشد تا بتوان الگوریتم های یادگیری ماشین را برای تولید ASR  پیاده سازی کرد راه های گوناگونی برای برای پیدا کردن ویژگی ها وجود دارد که آنهایی که در این مسئله مورد استفاده قرار داده شده اند به شرح زیر می باشد:
				1- یMFCC: مانند سریه فوریه عمل کرده و صوت های را به باند های فرکانسی تبدیل میکند 
				2-یPLP: این روش برای تشخیص ویژگی هایی صوت مستقل از گوینده آن به کار می رود بنابرین با کمک PLP و شکل های دیگر آن RASTA-PLP                                                    میتوان به کلاس بندی ها چگونگی تشخیص حروف  و اعداد را آموزش داد.	
					**تهیه مجموعه داده:**
					برای جمع آوری داده های مورد نیاز از آنجایی که ارزیابی دقیق و رسمی از کپچاهای صوتی وجود ندارد از کپچاهای موجود در سایت های رسمی استفاده شده است. و نزدیک 1000 کپچا جمع آوری شده که 900 تای آن برای آموزش و 100 عدد برای تست مورد استفاد قرار داده شده است. هر صوت به بخش های کوچکی تقسیم شده که داری حرف یا عدد یا یک نویز می باشند و روند پیدا کردن این سگمنت ها به این صورت است که هر جای صوت به یک پیک برخورد کرده است آن را یک سگمنت در نظر گرفته وطول تمام سگمنت ها با هم برابر است و یک سایز مشخص است.
					**روند حل مسئله**
					برای شناسایی و برچسب گذاری سگمنت های استخراج شده از سه الگوریتم زیر استفاده شده است:
				1-Support Vector Machin
 			2-AdaBoost
  			3-K-neaarest neighbor
  			به این شکل که ورودی ما یک قطعه از کپچای صوتی می باشد و خروجی ان برچسب ان قطع است این روند تکرار می شود تا هیچ تکه ای بدون برچسب نماند و حداکثرطول  راه حل بدست اید و تضمین می شود که هیچگاه طول راه حلی که یافت می شود از راه حل واقعی  بیشتر نیست .
  			در انتها به بررسی انواع کپچاهای صوتی و توانایی الگوریتم های ذکر شده در شکست آن ها را بررسی کرده است:
  			1-یgoogle audio captcha: شامل یک بلندگو می باشد که اعداد رندوم بین 0-9 می گوید و در پس زمینه آن صدای انسان با volume های مختلف استفاده شده است. الگوریتم SVM با احتمال 67 درصد توانایی حل کامل مسئله را دارد.
  			2-یcaptcha: مانند قبلی شامد یک بلندگو می باشد که ترکیبی از اعداد و حروف را می گوید و در پس زمینه آن صداهایی مانند چکیدن آب ...  موجود است
که این نویز ها در کل فایل پیوسته نیستند. الگوریتم SVM با احتمال 71 درصد توانایی حل کامل مسئله را دارد.
		3-یrecaptcha audio: شامل چند نوع بلند گو میباشد که اعداد را بصورت رندوم می گویند و در پس زمینه آن صدای انسان با volume های مختلف پخش می شود. الگوریتم SVM با احتمال 45 درصد توانایی حل کامل مسئله را دارد.
		الگوریتم های دیگر به کار رفته توانایشان در حا این مسئله کمتر از SVM میباشد برای اطلاعات بیشتر میتوانید به پاورقی مراجعه کنید.
		

 				
								
						
			
			

******2-****Recaptcha**

recaptcha  نوعی دیگر از کپچا است که
با در نظر داشتن دو هدف زیر ارائه داد:
 1- حداقل رساندن تلاش  و زمان شکستن کپچا کاربران مشروع  2- کامپیوتر ها نیاز به تکنیک های پیشرفته تری نسبت به شناسایی متن باید داشته باشند.
به گفته گوگل recaptcha نسبت دارای ویژگی های کاربرپسند و امنیت بالا نسبت به کپچاهای قبلی می باشد.
به بررسی ساختار recaptcha می پردازیم:
ویجت: ویجت زمانیکه که لود می شود مجموعه ای اطلاعات را درباره ی مرورگر کاربر به سرور می فرستد و سرور یک سری چک برای تایید مرورگر کاربر انجام می دهد.
روش کار به چه صورت است!!!
کاربر زمانیکه checkbox را کلیک میکند در خواستی حاوی اطلاعات زیر به گوگل فرستاده می شود

1-  Referrer (ارجاع دهنده)
2-  Sitekey ( هنگام ثبت نام در کپچا به سایت داده می شود)
3-  کوکی برای سایت گوگل
4-  اطلاعاتی که بدست آمده توسط ویجت


سپس درخواست توسط  advanced risk analyses system که با بررسی تاریخچه مروگر , محیط مرورگر , الگوی حرکتی موس و  ....  تصمیم میگیرد چه نوع کپچایی را برای کاربر به نمایش بگذارد.
چالش های ریکپچا:
1-  اگر یک کاربر مشهور باشید سیستم کپچا را حل شده در نظر گرفته و کاربر پذیرفته می شود.
2-  نمایش عکس: بصورت عمومی دارای یک عکس نمونه و نه عکس کاندید می باشد که کاربر باید عکس هایی را که از نظر معنایی شبیه به عکس نمونه هستنند را انتخاب کند. تعداد عکس های مرتبط در اکثر موارد بین 2-4 می باشد.
3-  متن ریکپچا: اگر سیستم شما را به عنوان یک کاربر مشکوک شناسایی کند آنگاه چالش تشخیص متن را برای شما در نظر میگیرد.

برای شکستن چالش دوم میتوان از کتابخانه و الگوریتم های زیر کمک گرفت:[4]

GRIS 2-clarifai     3-TDL         4-NuralTalk          5- Caffe 
با استفاده از الگوریتم های فوق تا درصد بالایی از کپچاها شکسته می شوند.


# آزمایش‌ها
برای شکستن یک کپچا چند گام اساسی داریم که به ترتیب آنها را باید طی شود پس از معرفی گام ها روش حل هر کدام را بررسی میکنیم:
1-از بین بردن نویز تصویر
2-شناسایی حروف موجود در عکس
3-برچسب زنی به حروف مشخص شده
**از بین بردن نویز تصویر:**
ابتدا برای اینکه شناسایی نویز ها و حروف آسان بشود عکس را به باینری تبدیل میکنیم که تمام نقاط تبدیل به نقاطی به رنگ سیاه یا سفید میکند برای این کار از تابع  cv2.threshold  استفاده میکنیم که انواع مختلفی دارد که در زیر به بردن نام آنها کفایت کرده:
1-cv2.THRESH_BINARY
2-cv2.THRESH_BINARY_INV
3- cv2.THRESH_TRUNC
4- cv2.THRESH_TOZERO
5- cv2.THRESH_TOZERO_INV

	imgGray = cv2.cvtColor(imgTestingNumbers, cv2.COLOR_BGR2GRAY) 
	_,imthresh = cv2.threshold(imgGray, 127, 255,cv2.THRESH_TRUNC)

از بین موارد نام برده شده  با توجه به تجربه تابع cv2.thresh_trunc کارایی بهتری دارد.  نوع دیگری از cv2.threshold داریم که بعد از اعمال توابع بالا
برای واضح تر شدن و بالاتر رفتن کیفیت می توان از ان استفاده کرد. Adaptive thresholding که اساس کار ان با توجه به نقاط همسایه یک نقطه است و بطور محلی شروع به باینری کردن هر نقطه میکند. و دوتابع به شرح زیر دارد که:
1-cv2.ADAPTIVE_THRESH_MEAN_C 
2-cv2.ADAPTIVE_THRESH_GAUSSIAN_C 
	که ما از تابع دوم استفاده میکنیم.
	...

      imgThresh = cv2.adaptiveThreshold(imgBlurred,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,       
                                      cv2.THRESH_BINARY_INV,11, 2)
بعد از اینکه عکس را به باینری تبدیل کردیم باید سعی کنیم نویز های ان را از بین ببریم شاید مهم ترین چالش در شکستن کپچاها از بین بردن نویز ها باشد زیرا بیشترین مشکل را در شناسایی حروف ایجاد کرده و باعث می شود تا الگوریتم های بکار رفته شده نتوانند بدرستی حروف را تشخیص دهند. در اینجا از تابع cv2.bluring استفاده میکنیم که هدف اصلی آن از بین بردن نویز تصاویر می باشد  و اساس کارآن به این صورت است که میانگین همسایه های یک نقطه را بدست می اورد و بجای ان نقطه جایگزین میکند که ما ازبین تارشدگی های متفاوت تابع cv2.GaussianBlur() را مورد استفاده قرار می دهیم.
**شناسایی حروف موجود در عکس**
برای شناسایی حروف موجود در عکس از cv2.contouring که برای آنالیز عکس و شناسایی شی ها استفاده میشود  برای مثال میتوان به عکس زیر توجه کرد
![توضیح تصویر](https://boute.s3.amazonaws.com/270-photo_2017-12-27_21-48-06.jpg)

	imgContours, npaContours, npaHierarchy = cv2.findContours(imgThreshCopy,             
                                                 cv2.RETR_EXTERNAL,         
                                                 cv2.CHAIN_APPROX_SIMPLE)  
    image = cv2.drawContours( imgTestingNumbers, npaContours, -1, (0,255,0), 2)

در عکس فوق مشاهده می شود خطوط سبز رنگ دور حروف کشیده شده. و بعد از اینکه چک میکنیم آیا خطوط رسم شده قابل قبول هستند یا نه! از سمت چپ شروع به تکه تکه کردن آن میکنیم البته اینجا به دلیل اینکه ممکن است دو حرف به یکدیگر متصل باشند یا یک حرف تبدیل به دو قسمت شود مشکل ایجاد شود که باید سعی کنیم برای contour  ها را محدود به شرایط خاصی کنیم.
**برچسب زنی به حروف مشخص شده**
در این مرحله باید حروف مشخص شده در مرحله قبل را به بردار تبدیل کرده و و به شبکه عصبی بدهیم تا با داده های آموزشی مقایسه کرده و نزدیکترین بردار را با استفاده از الگوریتم های تقریب و درون یابی مشخص می شود
در این مرحله میتوان از دو الگوریتم 
1-K_nearest neighbor یا نزدیکترین همسایه 
2-support vector machin
در این مرحله یک عکس را که داری همه ی حروف کوچک و بزرگ و اعداد می باشد را تکه تکه کردم  وب طور دستی انها را برچسب گذاری کردم و در یک فایل تکست, بردار و برچسب آنها را ذخیره کردم  و با تبدیل تکه های عکس بدست امده در مرحله قبل و تبدیل آن به یک بردار با الگوریتم K-NN نزدیکترین بردار را می یابیم و این قطعه عکس را برچسب گذاری میکنیم.
در قطعه کد زیر دو فایل  npaClassifications  وnpaFlattenedImages   که بترتیب اولی جواب بردار و دومی مجموعه بردار ها می باشد فایل دوم با استفاده از فایل اول اموزش داده می شود و هر بردار برچسب مورد نظر خود را میگیرد
	kNearest.train(npaFlattenedImages, cv2.ml.ROW_SAMPLE, npaClassifications)
در کد زیر از شبکه های استفاده نشده است در مرحله ی بعدی با پیدا کردن یک پایگاه داده  و پیاده سازی شبکه عصبی میتوان بجای استفاده از یک فایل شناسایی قطعه مورد نظر را به شبکه عصبی واگذار نمود با اینکار دقت کد بالا رفته و به کپچاها با احتمال بهتری شکسته می شوند.
 [break captcha](https://github.com/fatemeakbari/break_captcha2.git)
# بهبود کار
در بخش پیشین سعی کردیم با یک مجموعه داده کوچک به شناسایی حروف استخراج شده از عکس بپردازیم در این بخش میخواهیم با استفاده از یک مجموعه داده بزرگتر و همچنین استفاده از شبکه های عصبی[6] دقت کار را بالا ببریم و روشی مطمئن تر برای شکستن کپچاها در پیش بگیریم.
**گام اول:**
		اولین قدم برای حل کپچاها, جمع آوری داده می باشد برای همین ابتدا به پیدا کردن داده مناسب می پردازیم از این رو با استفاده از فایل download_images شروع به دانلود کپچاهای مورد نظر خودمان می کنیم که من در اینجا کپچای شریف را انتخاب کرده ام[7]برای اینکه شبکه عصبی بدرستی آموزش ببیند باید تعداد مناسبی کپچا  در اختیار داشته باشیم  با تجربه حداقل کپچای مورد نیاز ما 200 عدد می باشد که هر کدام شامل 4 حرف می باشد و در نهایت 800 عکس برای شبکه عصبی تهیه می شود. اگر داده های ما کم باشند شبکه ی عصبی به درستی آموزش نمی بیند که در بخش های بعدی دقت آن را برای مقادیر مختلف در تعداد داده می بینیم .
		**گام دوم**
		   بعد از دانلود کپچاها حالا باید آن را تکه تکه نمود و هر تکه را برچسب گذاری کرد و مشخص کنیم هر عکس چه عددی را نشان می دهد برای اینکه کار میتوان با از فتوشاپ یا gimp یا... استفاده نمود که عکس را تکه تکه کرد و عددی را که نشان می دهد  مشخص کنیم اما اینکار خیلی زمان بر و ملال آور می باشد برای همین فایل anonnate.py را استفاده می کنیم در این فایل ابتدا عکس را تبدیل به باینری کرده و سپس به عکس حاشیه اضافه می کنیم زیرا اگر یک حرف در عکس به لبه ها چسبیده باشد نمی توان برای یادگیری ماشین استفاده کرد.
![orginal image](https://boute.s3.amazonaws.com/270-22.png)
![padding the image](https://boute.s3.amazonaws.com/270-1.png)
سپس سعی در پیدا کردن حروف با counter  ها می کنیم و چهار ناحیه ای که بزرگتر از همه هستند را انتخاب می کنیم و بصورت دستی حرف مشخص شده را برچسب گذاری کرده,  بطور مثال اگر عدد 6 را فشار دهید عکس در مسیر زیر ذخیره می شود:
Dataset\6
![](https://boute.s3.amazonaws.com/270-34.png)
و به همین شکل تمام عکس ها قطعه قطعه شده و برچسب گذاری می شوند تا به عنوان داده بتوان از انها استفاده نمود.
**گام سوم**
در این بخش به اموزش شبکه ی عصبی می پردازیم ابتدا عکس ها را باید بخوانیم و سپس تبدیل  به یک ارایه کنیم قبل از اینکه عکس ها را به ارایه مورد نظر تبدیل کنیم  باید سایز همه ی عکس ها را ثابت و همسان هم نمود اینکار برای آموزش شبکه عصبی نیاز است برای همین از تابع preprocess که درون captchahelper.py تعریف شده است استفاده میکنیم که با الگوریتمی بسیار ساده و مقایسه کردن طول و عرض عکس سعی در یکی کردن طول و عرض بطوری که که هر کدام شامل 28 پیکسل باشند میکند. برچسب هر عکس را هم با توجه به فولدری که از آن عکس را میخوانیم مشخص می کنیم.
سپس  داده ها را به دو قسمت آموزش و تست تقسیم میکنیم قسمت اول برای برای آموزش شبکه عصبی و قسمت دوم نیز برای  بررسی دقت استفاده می شود.
حالا نوبت به ساخت مدل شبکه ی عصبی میرسد منظور از مدل اینجا تعداد لایه های بکار رفته و خصوصیات آنها می باشد[8] که از کلاس LeNet که درون فایل lenet می باشد استفاده می کنیم [9]که شامل سه ورودی طول و عرض و ارتفاع و عمق (در اینجا چون عکس ها را باینری کرده ایم عمق یک می باشد) و تعداد کلاس ها و آدرس فایلی که  مدل آموزش دیده قرار است در آن ذخیره شود است. طول و عرض را در مرحله قبل برای تمام عکس مقدار ثابت 28 کردیم همچنین تعداد کلاس ها 10 می باشد و یک فایل lenet_widths.hdf5 برای ذخیره مدل در نظر می گیریم.
بعداز ساخت مدل, داده های اموزشی را به مدل می دهیم  و  اموزش می‌بیند.
در چند شکل زیر دقت شبکه عصبی برای دو مقدار متفاوت داده نمایش داده شده است:
![](https://boute.s3.amazonaws.com/270-test1.png)
![evaluating network-
تعداد عکس های دانلود شده:100](https://boute.s3.amazonaws.com/270-t2.png)
همانطور که در دوعکس بالا مشاهده می‌کنیم با تعداد تقریبی 100 کپچا حدود 300 عکس میتوان تهیه کرد اما دیده می شود که مدل ما بدرستی آموزش ندیده است و میزان tarin_loss, val_loss هنوز خیلی بالا می باشد. بزرگی پایگاه داده برای حل مسئله کپچا خیلی مهم می باشد بطوری که که اگر تعداد کپچاهای دانلود شده را به 200 افزایش دهیم حدود 700 عکس تولید می شود با مقایسه نمودار های زیر و نمودار قبلی تفاوت را بخوبی احساس می‌کنیم.
![](https://boute.s3.amazonaws.com/270-test50.png)
![evaluating network-تعداد عکس های  دانلود شده:200](https://boute.s3.amazonaws.com/270-test45.png)
**گام چهارم**
میتوان گفت که دیگر کار ما به اتمام رسیده است در این بخش میخواهیم یکی از کپچاهای دانلود شده را به شبکه ی عصبی بدهیم تا آن را شناسایی کند در فاز قبلی بطور کامل درباره ی نحوه ی از بین بردن نویز و پیدا کردن حروف توضیح داده شده است و تکرار دوباره ی آن ملال آور می باشد. 
ابتدا مدل آموزش دیده را که در output\lenet_weights.hdf5 ذخیره کرده بودیم لود می‌کنیم و با استفاده از تابع predict سعی در شناسایی حرفی که در هر تکه عکس موجود است می‌کنیم.
![نمونه ی  تشخیص کپچا توسط شبکه ی عصبی](https://boute.s3.amazonaws.com/270-final.png)
 در روند کل پروژه کتاب deep learing for computer vision with python  را می توان راهنما و مرجع در نظر گرفت.[10]
 [لینک پیاده سازی](https://github.com/fatemeakbari/final-break-captcha)
# کارهای آینده 
			با توجه به وابستگی حل این مسئله به تعداد داده, اگر مجموعه داده خود را بزرگتر با احتمالی نزدیک به 100 میتوان تمام کپچا ها را شکست. باید توجه داشت که کپچای شریف در پس زمینه ی خود شامل نویز خاصی نبود. میتوان گفت شاید سخت ترین قسمت کار از بین بردن نویز های تصاویر می باشد که می توان روی این قسمت تمرکز بیشتری  کرد.

# مراجع
1- http://www.captcha.net/
2- https://websima.com/captcha-%DA%A9%D9%BE%DA%86%D8%A7/
3- http://www.captcha.net/Breaking_Audio_CAPTCHAs.pdf
4- https://www.blackhat.com/docs/asia-16/materials/asia-16-Sivakorn-Im-Not-a-Human-Breaking-the-Google-reCAPTCHA-wp.pdf
5- https://click.ir/1395/07/14/persian-captcha-was-born/
6- https://en.wikipedia.org/wiki/Convolutional_neural_network
7- http://edu.sharif.edu/jcaptcha.jpg
8- http://deeplearning.ir/%D8%A2%D9%85%D9%88%D8%B2%D8%B4-%D8%B4%D8%A8%DA%A9%D9%87-%DA%A9%D8%A7%D9%86%D9%88%D9%84%D9%88%D8%B4%D9%86-%D8%A8%D8%AE%D8%B4-%D8%A7%D9%88%D9%84/
9- https://www.pyimagesearch.com/2016/08/01/lenet-convolutional-neural-network-in-python/
10- https://getdpd.com/cart/hoplink/20252?referrer=1kfcbhtqp2n4oc0

# پیوندهای مفید

+ [کتابخانه اپن‌سی‌وی](http://opencv.org/)
+ [اپن‌سی‌وی در پایتون](http://docs.opencv.org/trunk/doc/py_tutorials/py_tutorials.html)
+ [بینایی کامپیوتری در جاوا اسکریپت](http://inspirit.github.io/jsfeat/) +[شبکه‌های عصبی در جاوا اسکریپت](https://github.com/harthur/brain)
+ [شبکه‌های عصبی کانلوشنال در جاوا اسکریپت](https://github.com/karpathy/convnetjs)
+ [یک منبع خوب](http://stackoverflow.com/questions/9413216/simple-digit-recognition-ocr-in-opencv-python)
+ [پیاده‌سازی svm در جاوا اسکریپت](https://github.com/karpathy/svmjs)
+ [پایگاه داده نمونه](http://www.cs.cmu.edu/~guestrin/Class/10701/projects.html#image)