Inajaribu kitambua CAPTCHA zima. Utambuzi wa Captcha: Mbinu na teknolojia Saraka na uongozi wao

Watu wengi hawajui, lakini nadharia yangu ilikuwa mpango wa kusoma maandishi kutoka kwa picha. Nilidhani kwamba ikiwa ningeweza kupata kiwango cha juu cha utambuzi, inaweza kutumika kuboresha matokeo ya utafutaji. Mshauri wangu bora, Dk. Gao Junbing, alipendekeza kwamba niandike tasnifu kuhusu mada hii. Hatimaye nilipata wakati wa kuandika makala hii na hapa nitajaribu kuzungumza juu ya kila kitu nilichojifunza. Ikiwa tu kulikuwa na kitu kama hiki wakati nilianza ...

Kama nilivyosema awali, nilikuwa najaribu kuchukua picha za kawaida kutoka kwa mtandao na kutoa maandishi kutoka kwao ili kuboresha matokeo ya utafutaji. Mawazo yangu mengi yalitokana na njia za kupasuka kwa captcha. Kama kila mtu anavyojua, captcha ni mambo ya kuudhi kama vile "Weka herufi unazoziona kwenye picha" kwenye kurasa za usajili au maoni.

Captcha imeundwa ili mtu aweze kusoma maandishi bila shida, wakati mashine haiwezi (hello, reCaptcha!). Kwa mazoezi, hii haikufanya kazi, kwa sababu karibu kila captcha iliyowekwa kwenye tovuti ilidukuliwa ndani ya miezi kadhaa.

Nilifanya vizuri - zaidi ya 60% ya picha zilitatuliwa kwa mafanikio kutoka kwa mkusanyiko wangu mdogo. Nzuri sana ukizingatia idadi ya picha mbalimbali kwenye mtandao.

Katika utafiti wangu, sikupata nyenzo zozote ambazo zingenisaidia. Ndiyo, kuna makala, lakini yana algorithms rahisi sana. Kwa kweli nilipata mifano michache iliyovunjika katika PHP na Perl, nilichukua vijisehemu vichache kutoka kwao na nikapata matokeo mazuri kwa captcha rahisi sana. Lakini hakuna hata mmoja wao aliyenisaidia sana, kwa sababu ilikuwa rahisi sana. Mimi ni mmoja wa watu ambao wanaweza kusoma nadharia, lakini hawawezi kuelewa chochote bila mifano halisi. Na katika makala nyingi iliandikwa kwamba hawatachapisha kanuni kwa sababu waliogopa kwamba ingetumiwa kwa madhumuni mabaya. Binafsi, nadhani captcha ni kupoteza wakati kwani ni rahisi sana kuzunguka ikiwa unajua jinsi gani.

Kwa kweli, kwa sababu ya ukosefu wa nyenzo zozote zinazoonyesha utapeli wa captcha kwa Kompyuta, niliandika nakala hii.

Tuanze. Hapa kuna orodha ya kile nitakachoshughulikia katika nakala hii:

  • Teknolojia zilizotumika
  • Captcha ni nini
  • Utambuzi wa picha kwa kutumia AI
  • Elimu
  • Kuweka yote pamoja
  • Matokeo na hitimisho

Teknolojia zilizotumika

Mifano yote imeandikwa katika Python 2.5 kwa kutumia maktaba ya PIL. Inapaswa kufanya kazi katika Python 2.6 pia.

Zisakinishe kwa mpangilio ulio hapo juu na uko tayari kutekeleza mifano.

Rudi nyuma

Katika mifano, nitaweka maadili mengi moja kwa moja kwenye nambari. Sina lengo la kuunda kitambua captcha cha ulimwengu wote, lakini kuonyesha tu jinsi inavyofanywa.

Captcha, ni nini?

Kimsingi captcha ni mfano wa ubadilishaji wa njia moja. Unaweza kwa urahisi kuchukua seti ya wahusika na kupata captcha kutoka humo, lakini si kinyume chake. Ujanja mwingine ni kwamba inapaswa kuwa rahisi kusomwa na wanadamu, lakini isiyoweza kutambulika kwa mashine. Captcha inaweza kuzingatiwa kama jaribio rahisi kama "Je, wewe ni mwanadamu?" Kimsingi zinatekelezwa kama taswira yenye alama au maneno fulani.

Zinatumika kuzuia barua taka kwenye tovuti nyingi za mtandao. Kwa mfano, captcha inaweza kupatikana kwenye ukurasa wa usajili wa Windows Live ID.

Unaonyeshwa picha, na ikiwa wewe ni mtu kweli, basi unahitaji kuingiza maandishi yake kwenye uwanja tofauti. Je, inaonekana kama wazo zuri ambalo linaweza kukulinda kutokana na maelfu ya usajili wa kiotomatiki kutuma barua taka au kusambaza Viagra kwenye mijadala yako? Shida ni kwamba AI, na haswa njia za utambuzi wa picha, zimepitia mabadiliko makubwa na zinafanya kazi vizuri katika maeneo fulani. OCR (utambuzi wa herufi za macho) ni sahihi kabisa siku hizi na inaweza kutambua maandishi yaliyochapishwa kwa urahisi. Uamuzi ulifanywa wa kuongeza rangi na laini ili kuifanya kompyuta kufanya kazi kwa bidii bila kusababisha usumbufu wowote kwa watumiaji. Hii ni aina ya mbio za silaha na, kama kawaida, wanakuja na silaha kali kwa ulinzi wowote. Kushinda captcha iliyoimarishwa ni ngumu zaidi, lakini bado inawezekana. Kwa kuongezea, picha inapaswa kubaki rahisi ili isiwaudhi watu wa kawaida.

Picha hii ni mfano wa kinasa tutakuwa tukifafanua. Hii ni captcha halisi, ambayo imewekwa kwenye tovuti halisi.

Hii ni captcha rahisi, ambayo ina alama za rangi sawa na ukubwa kwenye background nyeupe na kelele fulani (pixels, rangi, mistari). Unaweza kufikiria kuwa kelele hii ya nyuma ingefanya iwe ngumu kuitambua, lakini nitakuonyesha jinsi ya kuiondoa kwa urahisi. Ingawa hii sio captcha kali sana, ni mfano mzuri kwa programu yetu.

Jinsi ya kupata na kutoa maandishi kutoka kwa picha

Kuna njia nyingi za kuamua nafasi ya maandishi kwenye picha na kuiondoa. Kwa kutumia Google, unaweza kupata maelfu ya vifungu vinavyoelezea mbinu na kanuni mpya za kutafuta maandishi.

Kwa mfano huu nitatumia uchimbaji wa rangi. Ni mbinu rahisi sana ambayo nimepata matokeo mazuri nayo. Hii ndiyo mbinu niliyotumia katika tasnifu yangu.

Kwa mifano yetu, nitatumia algorithm ya mtengano wa picha yenye thamani nyingi. Kimsingi, hii ina maana kwamba kwanza tutapanga histogram ya rangi ya picha. Hii inafanywa kwa kuchukua saizi zote kwenye picha, zimewekwa kwa rangi, na kisha kuhesabu kwa kila kikundi. Ukiangalia captcha yetu ya jaribio, unaweza kuona rangi tatu kuu:

  • Mandhari nyeupe)
  • Grey (kelele)
  • Nyekundu (maandishi)

Katika Python hii itaonekana rahisi sana.

Msimbo ufuatao hufungua picha, na kuigeuza kuwa GIF (hurahisisha kazi yetu kwani ina rangi 255 pekee) na kuchapisha historia ya rangi.

Kutoka PIL kuleta Image im = Image.open("captcha.gif") im = im.convert("P") chapisha im.histogram()

Kama matokeo, tunapata zifuatazo:

Hapa tunaona idadi ya saizi za kila rangi 255 kwenye picha. Unaweza kuona kwamba nyeupe (255, ya hivi karibuni) ni ya kawaida zaidi. Inafuatiwa na nyekundu (maandishi). Ili kuthibitisha hili, wacha tuandike hati ndogo:

Kutoka kwa PIL kuleta Picha kutoka kwa opereta kuagiza itemgetter im = Image.open("captcha.gif") im = im.convert("P") yake = im.histogram() thamani = () kwa i katika anuwai (256) : maadili [i] = his[i] kwa j,k katika sorted(values.items(), key=itemgetter(1), reverse=True)[:10]: chapisha j,k

Na tunapata data ifuatayo:

Hii ni orodha ya rangi 10 zinazojulikana zaidi kwenye picha. Kama inavyotarajiwa, nyeupe hurudia mara nyingi. Kisha kuna kijivu na nyekundu.

Mara tu tukiwa na habari hii, tunaunda picha mpya kulingana na vikundi hivi vya rangi. Kwa kila rangi ya kawaida, tunaunda picha mpya ya binary (ya rangi 2), ambapo saizi za rangi hiyo zimejaa nyeusi na wengine na nyeupe.

Tuna rangi nyekundu kama rangi ya tatu inayojulikana zaidi na hiyo inamaanisha tunataka kuweka kundi la saizi zenye rangi 220. Nilipofanya majaribio niligundua kuwa rangi 220 inakaribia 220, kwa hivyo tutahifadhi kundi hilo la saizi pia. Nambari iliyo hapa chini inafungua captcha, kuibadilisha kuwa GIF, inaunda picha mpya ya ukubwa sawa na mandharinyuma nyeupe, na kisha inarudia kupitia picha asili ili kupata rangi tunayohitaji. Ikipata pikseli yenye rangi tunayohitaji, basi inatia alama saizi sawa katika picha ya pili yenye rangi nyeusi. Picha ya pili imehifadhiwa kabla ya kuondoka.

Kutoka kwa PIL kuleta Picha im = Image.open("captcha.gif") im = im.convert("P") im2 = Image.new("P",im.size,255) im = im.convert("P") ") temp = () kwa x katika masafa(im.size): kwa y katika masafa(im.size): pix = im.getpixel((y,x)) temp = pix if pix == 220 au pix == 227: # hizi ndizo nambari za kupata im2.putpixel((y,x),0) im2.save("output.gif")

Kuendesha kipande hiki cha msimbo hutupatia matokeo yafuatayo.

Katika picha unaweza kuona kwamba tumefanikiwa kutoa maandishi kutoka kwa nyuma. Ili kufanya mchakato huu otomatiki, unaweza kuchanganya maandishi ya kwanza na ya pili.

Ninakusikia ukiuliza: "Itakuwaje ikiwa maandishi kwenye captcha yameandikwa kwa rangi tofauti?" Ndio, vifaa vyetu bado vitaweza kufanya kazi. Fikiria kuwa rangi ya kawaida ni rangi ya mandharinyuma na kisha unaweza kupata rangi za mhusika.

Kwa hivyo katika hatua hii tumefanikiwa kutoa maandishi kutoka kwa picha. Hatua inayofuata ni kuamua ikiwa picha ina maandishi. Sitaandika nambari yoyote hapa kwa sasa, kwa sababu itafanya iwe ngumu kuelewa, wakati algorithm yenyewe ni rahisi sana.

Kwa kila taswira ya jozi: kwa kila pikseli katika picha ya jozi: ikiwa pikseli imewashwa: ikiwa pikseli yoyote ambayo tumeona hapo awali iko karibu nayo: ongeza kwa seti sawa: ongeza kwa seti mpya.

Matokeo ambayo utakuwa nayo ni seti ya mipaka ya wahusika. Kisha unachotakiwa kufanya ni kuzilinganisha na kila mmoja na kuona kama ziko thabiti. Ikiwa ndio, basi umeshinda jackpot na umetambua kwa usahihi alama karibu na kila mmoja. Unaweza pia kuangalia ukubwa wa maeneo yanayotokana au kuunda tu picha mpya na kuionyesha (mbinu ya show() ya picha) ili kuhakikisha usahihi wa algorithm.

Kutoka kwa PIL kuleta Picha im = Image.open("captcha.gif") im = im.convert("P") im2 = Image.new("P",im.size,255) im = im.convert("P") ") temp = () kwa x katika masafa(im.size): kwa y katika masafa(im.size): pix = im.getpixel((y,x)) temp = pix if pix == 220 au pix == 227: # hizi ndizo nambari za kupata im2.putpixel((y,x),0) # msimbo mpya unaanza hapa inletter = False foundletter=Flse start = 0 end = 0 herufi = kwa y in range(im2.size): # kipande kote kwa x katika safu(im2.size): # kipande chini pix = im2.getpixel((y,x)) ikiwa pix != 255: herufi = Kweli ikiwa imepatikana herufi == Si kweli na herufi == Kweli: foundletter = Mwanzo wa kweli = y ikiwa imepatikana herufi == Kweli na herufi == Si kweli: barua iliyopatikana = Mwisho wa uwongo = herufi y. ongeza ((kuanza, mwisho)) inletter=Herufi za uwongo

Kama matokeo, tulipata yafuatayo:

[(6, 14), (15, 25), (27, 35), (37, 46), (48, 56), (57, 67)]

Hizi ndizo nafasi za mlalo za mwanzo na mwisho wa kila mhusika.

AI na nafasi ya vekta katika utambuzi wa muundo

Utambuzi wa picha unaweza kuchukuliwa kuwa mafanikio makubwa zaidi ya AI ya kisasa, ikiruhusu kupenya aina zote za matumizi ya kibiashara. Mfano mzuri wa hii ni misimbo ya posta. Kwa kweli, katika nchi nyingi husomwa kiotomatiki, kwa kuwa kufundisha kompyuta kutambua nambari za nambari za simu ni kazi rahisi sana. Inaweza isiwe dhahiri, lakini utambuzi wa muundo unachukuliwa kuwa shida ya AI, ingawa ni maalum sana.

Takriban jambo la kwanza mtu hukutana nalo wakati wa kufahamiana na AI katika utambuzi wa muundo ni mitandao ya neva. Binafsi, sijawahi kufanikiwa na mitandao ya neural katika utambuzi wa mhusika. Kawaida mimi huifundisha alama 3-4, baada ya hapo usahihi hupungua sana kwamba itakuwa agizo la ukubwa wa juu ikiwa ningekisia alama bila mpangilio. Mwanzoni hii iliniletea hofu kidogo, kwa sababu hiki ndicho kilikuwa kiungo kilichokosekana katika tasnifu yangu. Kwa bahati nzuri, hivi majuzi nilisoma nakala kuhusu injini za utaftaji za nafasi ya vekta na nikapata kuwa njia mbadala ya kuainisha data. Mwishowe waligeuka kuwa chaguo bora kwa sababu ...

  1. Hazihitaji utafiti wa kina
  2. Unaweza kuongeza / kuondoa data isiyo sahihi na mara moja uone matokeo
  3. Wao ni rahisi kuelewa na kupanga
  4. Hutoa matokeo yaliyoainishwa ili uweze kuona X zinazolingana
  5. Huwezi kutambua kitu? Ongeza hii na unaweza kuitambua mara moja, hata ikiwa ni tofauti kabisa na kitu kilichotambuliwa hapo awali.

Bila shaka, hakuna jibini la bure. Drawback kuu ni kasi. Wanaweza kuwa polepole zaidi kuliko mitandao ya neva. Lakini nadhani faida zao bado zinazidi ubaya huu.

Ikiwa unataka kuelewa jinsi nafasi ya vector inavyofanya kazi, napendekeza kusoma Nadharia ya Injini ya Utafutaji wa Nafasi ya Vector. Hii ndio bora zaidi ambayo nimepata kwa wanaoanza.

Nilijenga utambuzi wangu wa picha kulingana na hati iliyotajwa hapo juu na hii ndiyo jambo la kwanza nililojaribu kuandika katika lugha yangu favorite, ambayo nilikuwa nikijifunza wakati huo. Soma waraka huu na ukishaelewa kiini chake, rudi hapa.

Tayari umerudi? Sawa. Sasa tunahitaji kupanga nafasi yetu ya vector. Kwa bahati nzuri, hii sio ngumu hata kidogo. Tuanze.

Ingiza Vector ya darasa la hisabatiLinganisha: def magnitude(binafsi,concordance): jumla = 0 kwa neno,hesabu katika concordance.iteritems(): jumla += count ** 2 rejesha math.sqrt(jumla) def relation(self,concordance1, concordance2) : umuhimu = 0 thamani ya juu = 0 kwa neno, hesabu katika upatanisho1.iteritems(): ikiwa concordance2.has_key(neno): thamani ya juu += hesabu * concordance2 rudisha thamani ya juu / (self.magnitude(concordance1) * self.magnitude(concordance2)

Huu ni utekelezaji wa Python wa nafasi ya vekta katika mistari 15. Kimsingi inachukua kamusi 2 tu na kutema nambari kati ya 0 na 1 inayoonyesha jinsi zinavyohusiana. 0 inamaanisha kuwa hazihusiani, na 1 inamaanisha kuwa zinafanana.

Elimu

Jambo linalofuata tunalohitaji ni seti ya picha ambazo tutalinganisha alama zetu. Tunahitaji seti ya mafunzo. Seti hii inaweza kutumika kufunza aina yoyote ya AI tutakayotumia (mitandao ya neva, n.k.).

Data inayotumiwa inaweza kuwa ya kuamua kwa mafanikio ya utambuzi. Kadiri data inavyokuwa bora, ndivyo uwezekano wa kufaulu unavyoongezeka. Kwa kuwa tunapanga kutambua captcha mahususi na tayari tunaweza kutoa herufi kutoka kwayo, kwa nini tusizitumie kama seti ya mafunzo?

Ndivyo nilivyofanya. Nilipakua captcha nyingi zilizotengenezwa na programu yangu iliigawanya kuwa herufi. Kisha nikakusanya picha zilizosababisha katika makusanyo (vikundi). Baada ya majaribio kadhaa, nilikuwa na angalau mfano mmoja wa kila herufi ambayo captcha ilitoa. Kuongeza mifano zaidi kutaongeza usahihi wa utambuzi, lakini hii ilitosha kwangu kudhibitisha nadharia yangu.

Kutoka kwa PIL kuagiza Muda wa kuagiza hahlib im = Image.open("captcha.gif") im2 = Image.new("P", im.size,255) im = im.convert("P") temp = () chapisha im.histogram() kwa x katika masafa(im.size): kwa y katika masafa(im.size): pix = im.getpixel((y,x)) temp = pix if pix == 220 au pix == 227: # hizi ndizo nambari za kupata im2.putpixel((y,x),0) inletter = False foundletter=Mwanzo potofu = 0 mwisho = herufi 0 = kwa y katika safu(im2.size): # kipande kote kwa x katika anuwai(im2.size): # kipande chini pix = im2.getpixel((y,x)) ikiwa pix != 255: inletter = Kweli ikiwa imepatikana herufi == Si kweli na herufi == Kweli: foundletter = Mwanzo wa kweli = y ikiwa foundletter == Kweli na herufi == Si kweli: foundletter = False end = y letters.append((anza,mwisho)) inletter=Flse # Msimbo mpya umefika. Tunatoa kila picha na kuihifadhi kwenye diski na # kile ambacho tunatumaini kuwa hesabu ya jina la kipekee = 0 kwa herufi katika herufi: m = hahlib.md5() im3 = im2.crop((barua , 0, herufi,im2.size) ) m.sasisha("%s%s"%(muda.time(),hesabu)) im3.save("./%s.gif"%(m.hexdigest()))) hesabu += 1

Kwenye pato tunapata seti ya picha kwenye saraka sawa. Kila mmoja wao amepewa heshi ya kipekee ikiwa utachakata captcha nyingi.
Hapa kuna matokeo ya nambari hii ya captcha yetu ya jaribio:

Ni juu yako jinsi ya kuhifadhi picha hizi, lakini niliziweka tu kwenye saraka zilizo na jina sawa na picha (alama au nambari).

Kuweka yote pamoja

Hatua ya mwisho. Tuna uchimbaji wa maandishi, uchimbaji wa herufi, mbinu ya utambuzi na seti ya mafunzo.

Tunapata picha ya captcha, chagua maandishi, pata wahusika, na kisha ulinganishe na seti yetu ya mafunzo. Unaweza kupakua programu ya mwisho na seti ya mafunzo na idadi ndogo ya captcha kutoka kwa kiungo hiki.

Hapa tunapakia tu seti ya mafunzo ili tuweze kulinganisha nayo:

Def buildvector(im): d1 = () count = 0 kwa i katika im.getdata(): d1 = nahesabu += 1 kurudi d1 v = VectorCompare() iconset = ["0","1","2" ,"3","4","5","6",7","8","9","0","a","b","c","d"," e","f","g","h","i","j","k","l","m","n","o","p","q" ,"r","s","t","u","v","w","x","y","z"] picha = kwa herufi katika iconset: kwa img in os.listdir ("./iconset/%s/"%(barua)): temp = if img != "Thumbs.db": temp.append(buildvector(Image.open("./iconset/%s/%s"% (barua, img)))) pichaset.append((barua:temp))

Na hapa ndipo uchawi wote hutokea. Tunaamua ambapo kila herufi iko na kuiangalia kwa kutumia nafasi yetu ya vekta. Kisha tunapanga matokeo na kuyachapisha.

Hesabu = 0 kwa herufi katika herufi: m = hahlib.md5() im3 = im2.crop((barua , 0, herufi,im2.size)) guess = kwa picha katika seti ya picha: kwa x,y in image.iteritems() : ikiwa len(y) != 0: guess.append((v.relation(y,buildvector(im3)),x)) guess.sort(reverse=Kweli) chapisha "", guess count += 1

hitimisho

Sasa tuna kila kitu tunachohitaji na tunaweza kujaribu kuanza mashine yetu ya miujiza.

Faili ya ingizo ni captcha.gif. Matokeo yanayotarajiwa: 7s9t9j

Python crack.py (0.96376811594202894, "7") (0.96234028545977002, "s") (0.9286884286888929, "9") (0.983503706098447) 3706098447 "9") (0.96989711688772628, "j")

Hapa tunaona ishara inayotarajiwa na kiwango cha kujiamini kuwa ni kweli (kutoka 0 hadi 1).

Inaonekana tumefaulu kweli!

Kwa kweli, kwenye captcha za majaribio, hati hii itatoa matokeo ya mafanikio katika takriban 22% ya kesi.

Python crack_test.py Mawazo Sahihi - 11.0 Mawazo Mabaya - Asilimia 37.0 Sahihi - 22.9166666667 Asilimia Si sahihi - 77.0833333333

Matokeo mengi yasiyo sahihi ni kwa sababu ya utambuzi usio sahihi wa nambari "0" na herufi "O". Hakuna kitu kisichotarajiwa, kwa sababu hata watu mara nyingi huwachanganya. Bado tuna tatizo la kugawanyika katika wahusika, lakini hili linaweza kutatuliwa kwa kuangalia matokeo ya mgawanyiko na kutafuta msingi wa kati.

Walakini, hata kwa algorithm isiyo kamili sana, tunaweza kutatua kila captcha ya tano kwa wakati ambao mtu hangekuwa na wakati wa kutatua hata moja.

Kuendesha nambari hii kwenye Core 2 Duo E6550 hutoa matokeo yafuatayo:

Mtumiaji halisi wa 0m5.750s 0m0.015s sys 0m0.000s

Kuna captcha 48 kwenye orodha yetu, ambayo inamaanisha kuwa kutatua moja huchukua takriban sekunde 0.12. Kwa kiwango chetu cha mafanikio cha 22%, tunaweza kutatua takribani captcha 432,000 kwa siku na kupata matokeo sahihi 95,040. Je, ikiwa unatumia multithreading?

Ni hayo tu. Natumaini kwamba uzoefu wangu utatumiwa na wewe kwa madhumuni mazuri. Najua unaweza kutumia nambari hii kufanya kitu kibaya, lakini ili kufanya kitu hatari sana lazima ubadilishe kidogo.

Kwa wale ambao wanajaribu kujilinda na captchas, naweza kusema kwamba hii haitakusaidia sana, kwa sababu unaweza kuzipita kwa utaratibu au kulipa tu watu wengine kuzitatua kwa mikono. Fikiria njia zingine za ulinzi.

Hili lilikuwa jina la kazi niliyowasilisha kwenye shindano la kisayansi na uhandisi la Baltic, ambalo liliniletea kipande cha karatasi cha kupendeza chenye kitengo cha Kirumi, pamoja na kompyuta ndogo mpya kabisa.

Kazi ilihusisha kutambua CAPTCHA zinazotumiwa na makampuni makubwa ya simu za mkononi kwenye fomu zao za kutuma SMS na kuonyesha kwamba mbinu zao hazikufaulu. Ili sio kuumiza kiburi cha mtu yeyote, tutawaita waendeshaji hawa kwa mfano: nyekundu, njano, kijani na bluu.

Mradi ulipokea jina rasmi Captchure na isiyo rasmi Kuvunja Hatua za Usalama zenye kasoro. Ulinganifu wowote ni wa kubahatisha.

Cha ajabu, zote (sawa, karibu zote) za CAPTCHA hizi ziligeuka kuwa dhaifu kabisa. Matokeo ya chini kabisa - 20% - ni ya mwendeshaji wa manjano, ya juu - 86% - ya bluu. Kwa hivyo, ninaamini kwamba kazi ya "kuonyesha kutokuwa na ufanisi" imetatuliwa kwa ufanisi.

Sababu za kuchagua waendeshaji wa seli ni ndogo. Niliambia Baraza la Wanasheria mashuhuri la Kisayansi hadithi kwamba “waendeshaji simu wana pesa za kutosha kuajiri mtayarishaji programu wa sifa zozote, na, wakati huo huo, wanahitaji kupunguza kiasi cha barua taka; kwa hivyo, CAPTCHAs zao zinapaswa kuwa na nguvu kabisa, ambayo utafiti wangu unaonyesha sivyo. Kwa kweli, kila kitu kilikuwa rahisi zaidi. Nilitaka kupata uzoefu kwa kuvunja na kutambua baadhi ya CAPTCHA rahisi, na nilichagua opereta nyekundu kama mwathirika wa CAPTCHA. Na baada ya hapo, hadithi iliyotajwa hapo juu ilizaliwa nyuma.

Kwa hivyo, karibu na mwili. Sina algoriti yoyote ya hali ya juu ya kutambua aina zote nne za CAPTCHA; Badala yake, niliandika algoriti 4 tofauti kwa kila aina ya CAPTCHA kando. Hata hivyo, licha ya ukweli kwamba algorithms ni tofauti kwa undani, kwa ujumla waligeuka kuwa sawa sana.

Kama waandishi wengi walionitangulia, nilivunja tatizo la utambuzi wa CAPTCHA katika kazi ndogo 3: usindikaji wa awali (uchakataji), ugawaji na utambuzi. Katika hatua ya awali, kelele mbalimbali, uharibifu, nk huondolewa kwenye picha ya chanzo Katika sehemu, wahusika binafsi hutengwa kutoka kwa picha ya chanzo na usindikaji wa baada ya kazi (kwa mfano, mzunguko wa nyuma). Wakati wa utambuzi, wahusika huchakatwa moja baada ya nyingine na mtandao wa neva uliofunzwa awali.

Mchakato wa awali tu ndio ulitofautiana sana. Hii ni kutokana na ukweli kwamba CAPTCHA tofauti hutumia mbinu tofauti za upotoshaji wa picha, na algorithms ya kuondoa uharibifu huu hutofautiana sana. Mgawanyiko ulitumia wazo kuu la kutafuta vifaa vilivyounganishwa na kengele ndogo na filimbi (ilibidi ziwe muhimu kwa zile zenye milia ya manjano tu). Utambuzi ulikuwa sawa kabisa kwa waendeshaji watatu kati ya wanne - tena, mwendeshaji wa manjano tu ndiye alikuwa tofauti.

Hatimaye, sehemu ndogo (chini ya 10px) nyeusi zilizounganishwa zimepakwa rangi nyeupe:

Wakati mwingine (mara chache, lakini hutokea) barua hugawanyika katika sehemu kadhaa; Ili kusahihisha kutokuelewana huku kwa kukasirisha, mimi hutumia njia rahisi ya kufikiria ambayo hutathmini ikiwa vipengee kadhaa vilivyounganishwa ni vya ishara moja. Alama hii inategemea tu nafasi ya mlalo na saizi ya visanduku vya kufunga vya kila herufi.

Ni rahisi kutambua kwamba alama nyingi ziliunganishwa katika sehemu moja iliyounganishwa, na kwa hiyo ni muhimu kuwatenganisha. Hapa ukweli kwamba picha daima ina wahusika 5 huja kuwaokoa. Hii hukuruhusu kuhesabu kwa usahihi mkubwa ni herufi ngapi katika kila sehemu inayopatikana.

Ili kuelezea kanuni ya uendeshaji wa algorithm kama hiyo, itabidi tuchunguze kwa undani zaidi kwenye vifaa. Wacha tuonyeshe idadi ya sehemu zilizopatikana na n, na safu ya upana ( alisema kwa usahihi, sawa?) ya sehemu zote za upana[n]. Tutafikiri kwamba ikiwa baada ya hatua zilizo hapo juu n > 5, picha haikuweza kutambuliwa. Wacha tuzingatie mtengano wote unaowezekana wa nambari 5 kuwa maneno chanya kamili. Kuna wachache wao - 16 tu. Kila mtengano huo unafanana na baadhi ya mpangilio unaowezekana wa alama kulingana na vipengele vilivyopatikana vilivyounganishwa. Ni jambo la busara kudhani kuwa kadiri sehemu inayopatikana inavyokuwa pana, ndivyo wahusika wengi inavyokuwa. Kutoka kwa upanuzi wote wa quintuple, tunachagua wale tu ambao idadi ya maneno ni sawa na n. Wacha tugawanye kila kipengele kutoka kwa upana kwa upana - kana kwamba tunairekebisha. Wacha tufanye vivyo hivyo na upanuzi wote uliobaki - tugawanye kila nambari ndani yao kwa muhula wa kwanza. Na sasa (tahadhari, mstari wa ngumi!) Hebu tukumbuke kwamba matokeo ya ns yaliyoagizwa yanaweza kufikiriwa kama pointi katika nafasi ya n-dimensional. Kwa kuzingatia hili, wacha tupate mtengano wa karibu wa Euclidean wa tano hadi upana wa kawaida. Hii ndiyo matokeo yanayotarajiwa.

Kwa njia, kuhusiana na algorithm hii, njia nyingine ya kuvutia ilikuja akilini mwangu kutafuta mtengano wote wa nambari kwa maneno, ambayo mimi, hata hivyo, sikuwahi kutekeleza, nikijizika katika miundo ya data ya Python. Kwa kifupi, inatoka wazi ikiwa unaona kuwa idadi ya mtengano wa urefu fulani inalingana na kiwango kinacholingana cha pembetatu ya Pascal. Walakini, nina hakika kuwa algorithm hii imejulikana kwa muda mrefu.

Kwa hivyo, baada ya kuamua idadi ya wahusika katika kila sehemu, heuristic inayofuata inakuja - tunaamini kuwa watenganishaji kati ya wahusika ni nyembamba kuliko wahusika wenyewe. Ili kuchukua fursa ya ujuzi huu wa siri, tutaweka vitenganishi vya n-1 kando ya sehemu, ambapo n ni idadi ya wahusika katika sehemu, baada ya hapo tutahesabu makadirio ya chini ya picha katika eneo ndogo la kila kitenganishi. . Kutokana na makadirio haya, tutapokea taarifa kuhusu ni saizi ngapi katika kila safu ni za wahusika. Hatimaye, katika kila makadirio tunapata kiwango cha chini na kusonga kitenganishi huko, baada ya hapo tunapunguza picha pamoja na watenganishaji hawa.

Hatimaye, kutambuliwa. Kama nilivyosema tayari, mimi hutumia mtandao wa neural kwa hiyo. Ili kuifunza, kwanza ninaendesha picha mia mbili chini ya kichwa cha kawaida kifaa cha treni kupitia hatua mbili za kwanza zilizoandikwa na zilizotatuliwa, kama matokeo ambayo ninapata folda iliyo na idadi kubwa ya sehemu zilizokatwa vizuri. Kisha, mimi husafisha uchafu kwa mikono yangu (matokeo ya mgawanyiko usio sahihi, kwa mfano), baada ya hapo ninaleta matokeo kwa ukubwa sawa na kuwapa FANN ili ivunjwe vipande vipande. Kwenye pato ninapata mtandao wa neva uliofunzwa, ambao hutumiwa kutambuliwa. Mpango huu ulishindwa mara moja tu - lakini zaidi juu ya hilo baadaye.

Kama matokeo, kwenye seti ya jaribio (haijatumika kwa mafunzo, jina la nambari - testset) kati ya picha 100, 45 zilitambuliwa kwa usahihi Matokeo yake sio ya juu sana - ni, bila shaka, inaweza kuboreshwa, kwa mfano, kwa kufafanua utangulizi au kufanya upya utambuzi, lakini, kusema ukweli, nilikuwa mvivu sana kutafakari. hiyo.

Kwa kuongeza, nilitumia kigezo kingine cha kutathmini utendaji wa algorithm - kosa la wastani. Ilihesabiwa kama ifuatavyo. Kwa kila picha, umbali wa Levenshtein ulipatikana kati ya maoni ya algoriti kuhusu picha hii na jibu sahihi - baada ya hapo maana ya hesabu ilichukuliwa juu ya picha zote. Kwa aina hii ya CAPTCHA, hitilafu ya wastani ilikuwa herufi 0.75/picha. Inaonekana kwangu kuwa hiki ni kigezo sahihi zaidi kuliko tu asilimia ya utambuzi.

Kwa njia, karibu kila mahali (isipokuwa kwa operator wa njano) nilitumia mpango huu hasa - picha 200 kwenye treni, 100 kwenye testset.

Kijani

Nilichagua zile za kijani kama lengo langu linalofuata - nilitaka kuchukua jambo zito zaidi kuliko kuchagua matrix ya upotoshaji.

Manufaa:

  • Athari ya 3D
  • Zungusha na ubadilishe
  • Mwangaza usio na usawa

Mapungufu:

  • Herufi ni nyeusi zaidi kuliko mandharinyuma
  • Upande wa juu wa mstatili unaonekana wazi - unaweza kutumika kwa mzunguko wa nyuma

Ilibadilika kuwa ingawa mapungufu haya yanaonekana kuwa duni, unyonyaji wao hufanya iwezekane kushughulikia faida zote kwa ufanisi sana.

Wacha tuanze tena na usindikaji wa mapema. Kwanza, hebu tukadirie pembe ya kuzunguka ya mstatili ambayo alama ziko. Ili kufanya hivyo, tumia Opereta ya Erode kwenye picha ya asili (tafuta kiwango cha chini cha ndani), kisha Kizingiti cha kuchagua mabaki ya mstatili na, hatimaye, inversion. Tunapata doa nyeupe nzuri kwenye historia nyeusi.

Inayofuata inakuja mawazo ya kina. Kwanza. Ili kukadiria angle ya mzunguko wa mstatili mzima, inatosha kukadiria angle ya mzunguko wa upande wake wa juu. Pili. Unaweza kukadiria pembe ya mzunguko wa upande wa juu kwa kutafuta mstari wa moja kwa moja sambamba na upande huo. Cha tatu. Ili kuelezea mstari wowote wa moja kwa moja, isipokuwa moja madhubuti ya wima, vigezo viwili vinatosha - uhamisho wa wima kutoka kwa kituo cha kuratibu na angle ya mwelekeo, na tunavutiwa tu na pili. Nne. Tatizo la kupata mstari ulionyooka linaweza kutatuliwa kwa kutotafuta sana - hakuna pembe kubwa sana za mzunguko, na hatuhitaji usahihi wa hali ya juu. Tano. Ili kupata mstari unaohitajika, unaweza kulinganisha kila mstari na makadirio ya jinsi iko karibu na unayotaka, na kisha uchague kiwango cha juu. Ya sita. Muhimu zaidi. Ili kukadiria pembe fulani ya mwelekeo wa mstari, fikiria kwamba picha iliyo hapo juu imeguswa na mstari wa moja kwa moja na pembe hii ya mwelekeo. Ni wazi kwamba kutoka kwa vipimo vya picha na angle ya mwelekeo, inawezekana kuhesabu bila shaka uhamishaji wa wima wa mstari wa moja kwa moja, ili uelezewe bila shaka. Ifuatayo, hatua kwa hatua tutasonga mstari huu wa moja kwa moja chini. Wakati fulani atagusa doa nyeupe. Wacha tukumbuke wakati huu na eneo la makutano ya mstari wa moja kwa moja na doa. Acha nikukumbushe kwamba mstari wa moja kwa moja una miunganisho 8 kwenye ndege, kwa hivyo kelele za hasira kutoka kwa watazamaji kwamba mstari wa moja kwa moja una mwelekeo mmoja, na eneo ni dhana ya pande mbili, hazifai hapa. Kisha, tutasonga mstari huu wa moja kwa moja chini kwa muda zaidi, tukikumbuka eneo la makutano kwa kila hatua, baada ya hapo tutafanya muhtasari wa matokeo yaliyopatikana. Kiasi hiki kitakuwa makadirio ya pembe hii ya mzunguko.

Kwa muhtasari wa hayo hapo juu: tutatafuta mstari ulionyooka ili kwamba inaposhuka chini ya picha, mwangaza wa saizi zilizo kwenye mstari huu ulionyooka huongezeka sana.

Kwa hiyo, pembe ya mzunguko imepatikana. Lakini hupaswi kukimbilia mara moja kutumia ujuzi uliopatikana. Ukweli ni kwamba hii itaharibu mshikamano wa picha, na bado tutaihitaji.

Hatua inayofuata ni kutenganisha wahusika kutoka nyuma. Ukweli kwamba alama ni nyeusi zaidi kuliko mandharinyuma itatusaidia sana hapa. Hatua ya mantiki kabisa kwa upande wa watengenezaji - vinginevyo picha itakuwa vigumu sana kusoma. Wale ambao hawaamini wanaweza kujaribu kuiga picha wenyewe na kujionea wenyewe.

Walakini, mbinu ya "nguvu kali" - jaribio la kukata herufi kwa kutumia mabadiliko ya kizingiti - haifanyi kazi hapa. Matokeo bora ambayo nilifanikiwa kupata - kwa t=140 - yanaonekana kusikitisha sana. Kuna taka nyingi sana zilizobaki nyuma. Kwa hivyo, ilibidi nitumie suluhisho. Wazo hapa ni lifuatalo. Alama kawaida hushikamana. Zaidi ya hayo, mara nyingi wao ni wa pointi nyeusi zaidi kwenye picha. Je, ikiwa unajaribu kuomba kujaza kutoka kwa pointi hizi za giza, na kisha kutupa maeneo madogo sana yaliyojaa - takataka dhahiri?

Matokeo yake ni, kusema ukweli, ya kushangaza. Katika picha nyingi, unaweza kuondokana na mandharinyuma kabisa. Walakini, hutokea kwamba ishara hugawanyika katika sehemu kadhaa - katika kesi hii, crutch moja katika sehemu inaweza kusaidia - lakini zaidi juu ya hilo baadaye.

Hatimaye, mchanganyiko wa waendeshaji wa Dilate na Erode huondoa mashimo madogo yaliyoachwa kwenye wahusika, ambayo husaidia kufanya utambuzi rahisi.

Kugawanya hapa ni rahisi zaidi kuliko mchakato wa awali. Kwanza kabisa, tunatafuta vipengele vilivyounganishwa.

Kisha, tunachanganya vipengele ambavyo viko karibu kwa usawa (utaratibu ni sawa na hapo awali):

Kanuni hii ilituruhusu kupata matokeo ya 69% ya picha zilizotambulika kwa mafanikio na kupata hitilafu ya wastani ya herufi 0.3/picha.

Bluu

Kwa hiyo, operator wa bluu alikuwa wa tatu kupokea hali ya "kushindwa". Ilikuwa, kwa kusema, pumziko kabla ya samaki wakubwa kabisa ...

Ni ngumu kuandika chochote kama faida, lakini nitajaribu:

  • Kuzungusha herufi ndicho kikwazo kikubwa au kidogo pekee
  • Kelele ya mandharinyuma kama ishara
  • Alama wakati mwingine hugusana

Tofauti na hii:

  • Mandharinyuma ni nyepesi zaidi kuliko wahusika
  • Alama zinafaa vizuri kwenye mstatili
  • Rangi tofauti za alama hufanya iwe rahisi kuwatenganisha kutoka kwa kila mmoja

Kwa hiyo, kabla ya mchakato. Wacha tuanze kwa kukata msingi. Kwa kuwa picha ni ya rangi tatu, tutaikata kwa njia, na kisha kutupa pointi zote ambazo ni mkali kuliko 116 katika njia zote. Tunapata mask hii nzuri:

Kisha, tunabadilisha picha kwenye nafasi ya rangi ya HSV (Wikipedia). Hii itahifadhi habari kuhusu rangi ya alama, na wakati huo huo uondoe gradient kutoka kwenye kando zao.

Wacha tutumie mask iliyopatikana hapo awali kwa matokeo:

Hii inahitimisha mchakato wa awali. Mgawanyiko pia ni mdogo sana. Wacha tuanze, kama kawaida, na vifaa vya unganisho:

Tunaweza kuishia hapo, lakini ikawa 73% pekee, ambayo hainifai hata kidogo - 4% tu bora kuliko matokeo ya CAPTCHA changamano zaidi. Kwa hivyo hatua inayofuata ni kugeuza mzunguko wa wahusika. Hapa tutahitaji ukweli kwamba tayari nimesema kwamba alama za ndani zinafaa vizuri kwenye mstatili. Wazo ni kupata mstatili unaofunga kwa kila herufi, na kisha utumie mteremko wake kuhesabu mteremko wa mhusika yenyewe. Hapa, kwa kuelezea mstatili tunamaanisha moja ambayo, kwanza, ina saizi zote za ishara fulani, na, pili, ina eneo ndogo zaidi ya yote iwezekanavyo. Ninatumia utekelezaji uliotengenezwa tayari wa algorithm ya kupata mstatili kama huo kutoka kwa OpenCV (MinAreaRect2).

Algoriti hii imefaulu kutambua 86% ya picha zilizo na hitilafu ya wastani ya herufi/picha 0.16, ambayo inathibitisha dhana kwamba hii ndiyo CAPTCHA rahisi zaidi. Walakini, mwendeshaji sio mkubwa zaidi ...

Njano

Sasa inakuja sehemu ya kufurahisha. Kwa hivyo kusema, apotheosis ya shughuli yangu ya ubunifu :) CAPTCHA hii ni kweli ngumu zaidi kwa kompyuta na, kwa bahati mbaya, kwa mtu.

Manufaa:

  • Kelele kwa namna ya matangazo na mistari
  • Zungusha na kupima alama
  • Funga mpangilio wa alama

Mapungufu:

  • Palette mdogo sana
  • Mistari yote ni nyembamba sana
  • Matangazo mara nyingi hayaingiliani na alama
  • Pembe ya mzunguko wa alama zote ni takriban sawa

Nilifikiria juu ya hatua ya kwanza kwa muda mrefu. Kitu cha kwanza kilichokuja kichwani ni kucheza na maxima wa ndani (Dilate) kuondoa kelele ndogo. Walakini, njia hii ilisababisha ukweli kwamba barua kidogo zilibaki - muhtasari mbaya tu. Shida ilizidishwa na ukweli kwamba muundo wa wahusika wenyewe sio sare - hii inaonekana wazi kwa ukuzaji wa hali ya juu. Ili kuiondoa, niliamua kuchagua njia ya kijinga - nilifungua Rangi na kuandika kanuni za rangi zote zilizopatikana kwenye picha. Ilibadilika kuwa kwa jumla kuna textures nne tofauti katika picha hizi, na tatu kati yao zina rangi 4 tofauti, na moja ya mwisho ina 3; Zaidi ya hayo, vipengele vyote vya rangi hizi viligeuka kuwa nyingi za 51. Kisha, nilikusanya meza ya rangi, kwa msaada ambao niliweza kuondokana na texture. Walakini, kabla ya "kuorodhesha" hii pia ninafuta saizi zote nyepesi sana ambazo kawaida huwa kwenye kingo za wahusika - vinginevyo lazima niweke alama kama kelele, kisha nishughulike nazo, wakati zina habari kidogo.

Kwa hivyo, baada ya mabadiliko haya, hakuna rangi zaidi ya 6 kwenye picha - rangi 4 za wahusika (tutaziita kwa kawaida kijivu, bluu, kijani kibichi na kijani kibichi), nyeupe (rangi ya asili) na "haijulikani", ikionyesha kuwa rangi ya pixel ni mahali pake haikuweza kutambuliwa na maua yoyote yanayojulikana. Ninaiita masharti - kwa sababu kwa wakati huu ninaondoa njia tatu na kuendelea na picha inayojulikana na rahisi ya monochrome.

Hatua inayofuata ilikuwa kufuta mistari kutoka kwa picha. Hapa hali imehifadhiwa na ukweli kwamba mistari hii ni nyembamba sana - pixel 1 tu. Kichujio rahisi kinajipendekeza: pitia picha nzima, ukilinganisha rangi ya kila pixel na rangi za majirani zake (kwa jozi - kwa wima na kwa usawa); ikiwa majirani yanafanana na rangi, na wakati huo huo haipatikani na rangi ya pixel yenyewe, fanya sawa na majirani. Ninatumia toleo la kisasa zaidi la kichungi sawa, ambacho kinafanya kazi katika hatua mbili. Kwa kwanza, anatathmini majirani kwa umbali wa 2, kwa pili - kwa umbali wa 1. Hii inakuwezesha kufikia athari zifuatazo:

Ifuatayo, ninaondoa madoa mengi, pamoja na rangi "isiyojulikana". Ili kufanya hivyo, mimi hutafuta kwanza maeneo yote madogo yaliyounganishwa (chini ya 15 katika eneo hilo, kwa usahihi), kuyatumia kwa mask nyeusi na nyeupe, na kisha kuchanganya matokeo na maeneo yaliyochukuliwa na rangi "isiyojulikana".

Kutumia masks haya, mimi hutumia algorithm ya Inpaint (au tuseme, utekelezaji wake katika OpenCV). Hii ni nzuri sana katika kuondoa uchafu mwingi kutoka kwa picha.

Walakini, utekelezaji wa OpenCV wa algorithm hii iliundwa kufanya kazi na picha na video, na sio kutambua picha zilizoundwa kwa maandishi na maandishi ya kelele. Baada ya kuitumia, gradient zinaonekana, ambazo tungependa kuziepuka ili kurahisisha ugawaji. Kwa hivyo, ni muhimu kufanya usindikaji wa ziada, yaani, kuimarisha. Kwa rangi ya kila pixel, ninahesabu ya karibu zaidi kutoka kwenye jedwali hapo juu (hebu nikumbushe, kuna rangi 5 - moja kwa kila moja ya textures ya tabia na nyeupe).

Hatimaye, hatua ya mwisho ya mchakato wa awali ni kuondoa maeneo yote madogo yaliyobaki yaliyounganishwa. Zinaonekana baada ya kutumia Inpaint, kwa hivyo hakuna marudio hapa.

Wacha tuendelee kwenye sehemu. Ni ngumu sana na ukweli kwamba alama ni karibu sana kwa kila mmoja. Inaweza kutokea kwamba nyuma ya ishara moja nusu ya nyingine haionekani. Inakuwa mbaya sana wakati alama hizi pia zina rangi sawa. Kwa kuongeza, uchafu pia una jukumu - inaweza kutokea kwamba katika picha ya awali kulikuwa na mistari mingi inayoingiliana katika sehemu moja. Katika kesi hii, algorithm ambayo nilielezea hapo awali haitaweza kuwaondoa.

Baada ya wiki iliyotumiwa katika majaribio yasiyo na matunda ya kuandika sehemu kwa njia sawa na katika kesi zilizopita, niliacha jambo hili na kubadilisha mbinu. Mkakati wangu mpya ulikuwa kugawanya mchakato mzima wa sehemu katika sehemu mbili. Katika kwanza, pembe ya mzunguko wa wahusika inakadiriwa na mzunguko wa kinyume unafanywa. Katika pili, wahusika huchaguliwa tena kutoka kwa picha iliyopanuliwa tayari. Basi hebu tuanze. Wacha tuanze, kama kawaida, kwa kutafuta vipengee vilivyounganishwa.

Kisha unahitaji kukadiria angle ya mzunguko wa kila ishara. Wakati nikifanya kazi na opereta ambaye alikuwa shabiki wa Greenpeace, nilikuja na algorithm ya hii, lakini niliandika na kuitumia hapa tu. Ili kuelezea kazi yake, nitatoa mlinganisho. Hebu fikiria bastola inayosogea kuelekea picha nyeusi na nyeupe ya ishara kutoka chini hadi juu. Ushughulikiaji wa pistoni ambao unasukuma iko kwa wima, jukwaa la kufanya kazi ambalo linasukuma ni la usawa, sambamba na chini ya picha na perpendicular kwa kushughulikia. Ushughulikiaji umeunganishwa kwenye jukwaa katikati, na kwenye sehemu ya kushikamana kuna kiungo kinachoweza kusongeshwa, kama matokeo ambayo jukwaa linaweza kuzunguka. Naomba wataalamu wa istilahi wanisamehe.

Ruhusu mpini usonge juu, ukisukuma pedi mbele yako kulingana na sheria za fizikia. Tutafikiri kwamba tu picha nyeupe ya ishara ni nyenzo, na pistoni hupita kwa urahisi kupitia historia nyeusi. Kisha pistoni, baada ya kufikia rangi nyeupe, itaanza kuingiliana nayo, yaani, kugeuka - mradi nguvu bado inatumika kwa kushughulikia. Anaweza kuacha katika matukio mawili: ikiwa anapiga ishara kwa pande zote mbili za hatua ya matumizi ya nguvu, au ikiwa anapiga ishara kwa uhakika wa matumizi ya nguvu. Katika visa vingine vyote, ataweza kuendelea kusonga mbele. Makini, kilele: tutafikiria kuwa pembe ya kuzunguka kwa ishara ni pembe ya mwelekeo wa pistoni wakati iliposimama.

Algorithm hii ni sahihi kabisa, lakini sizingatii matokeo ambayo ni wazi sana (zaidi ya digrii 27). Kutoka kwa wengine, napata maana ya hesabu, baada ya hapo ninazungusha picha nzima kwa kuondoa pembe hii. Kisha mimi hutafuta vipengele vilivyounganishwa tena.

Kisha inakuwa ya kuvutia zaidi na zaidi. Katika mifano ya awali, nilianza udanganyifu mbalimbali na sehemu zilizopokelewa, baada ya hapo nikazihamisha kwenye mtandao wa neural. Kila kitu ni tofauti hapa. Kwanza, ili angalau kurejesha sehemu ya habari iliyopotea baada ya kugawanya picha hiyo katika vipengele vilivyounganishwa, kwa kila moja yao mimi hupaka rangi ya kijivu giza (96) "background" - ni nini kilicho karibu na sehemu iliyokatwa, lakini ilikuwa. haijajumuishwa ndani yake , baada ya hapo ninapunguza muhtasari wa wahusika, kwa kutumia utaratibu sawa na katika utangulizi wa mistari (na umbali wa jirani sawa na moja).

Rasmi (kutoka kwa mtazamo wa moduli za programu), mgawanyiko unaisha hapa. Msomaji makini anaweza kuwa amegundua kuwa hakuna mahali palipotajwa kuwatenganisha wahusika waliokwama pamoja. Ndiyo, hiyo ni kweli - ninaziwasilisha ili zitambuliwe haswa katika fomu hii, na kisha kuzimaliza papo hapo.

Sababu ni kwamba njia ya kutenganisha wahusika iliyoshikamana ambayo ilielezewa hapo awali (na makadirio madogo zaidi) haifanyi kazi hapa - fonti ilichaguliwa na waandishi vizuri sana. Kwa hiyo, tunapaswa kuchukua mbinu tofauti, ngumu zaidi. Mbinu hii inatokana na wazo kwamba mtandao wa neva unaweza kutumika kwa mgawanyiko.

Hapo mwanzoni, nilielezea algorithm ambayo hukuruhusu kupata idadi ya wahusika katika sehemu kutokana na upana unaojulikana wa sehemu hii na jumla ya idadi ya wahusika. Algorithm sawa inatumika hapa. Kwa kila sehemu, idadi ya wahusika ndani yake huhesabiwa. Ikiwa kuna moja tu hapo, hakuna haja ya kuongeza chochote, na sehemu hii inatumwa mara moja >>= kwa mtandao wa neva. Ikiwa kuna alama zaidi ya moja, basi watenganishaji wanaowezekana huwekwa kwa umbali sawa kando ya sehemu. Kisha kila kitenganishi husogea katika kitongoji chake kidogo, na wakati huo huo mmenyuko wa mtandao wa neva kwa alama karibu na kitenganishi hiki huhesabiwa, baada ya hapo kinachobaki ni kuchagua kiwango cha juu (kwa kweli, yote haya hufanywa na a. algorithm ya kijinga, lakini, kwa kanuni, kila kitu ni takriban kama hii).

Kwa kawaida, ushiriki wa mtandao wa neva katika mchakato wa kugawanya (au ugawaji wa awali, ikiwa unapenda) haujumuishi uwezekano wa kutumia mpango wa mafunzo wa mtandao wa neural ambao tayari nimeelezea. Kwa usahihi zaidi, haikuruhusu kupata mtandao wa kwanza wa neva - inaweza kutumika kutoa mafunzo kwa wengine. Kwa hivyo, mimi hufanya hivyo kwa urahisi kabisa - mimi hutumia njia za kawaida za sehemu (makadirio) kutoa mafunzo kwa mtandao wa neva, wakati ninapoutumia, algorithm iliyoelezewa hapo juu inatumika.

Kuna hila moja zaidi inayohusishwa na matumizi ya mtandao wa neva katika kanuni hii. Katika mifano iliyotangulia, mtandao wa neva ulifunzwa kuhusu takriban matokeo mbichi ya usindikaji wa awali na sehemu. Hapa hii ilituruhusu kupata si zaidi ya 12% ya kutambuliwa kwa mafanikio. Hii kimsingi haikunifaa. Kwa hiyo, kabla ya kuanza enzi iliyofuata ya mafunzo ya mtandao wa neva, nilianzisha upotoshaji mbalimbali katika picha za awali, takriban nikiiga zile halisi: ongeza dots nyeupe/kijivu/nyeusi, mistari ya kijivu/miduara/mstatili, zunguka. Pia niliongeza seti ya treni kutoka picha 200 hadi 300 na kuongeza kinachojulikana halali kuangalia ubora wa mafunzo wakati wa mafunzo juu ya picha 100. Hii ilifanya iwezekane kufikia ongezeko la tija kwa takriban asilimia tano, na pamoja na kugawanywa na mtandao wa neva, ilitoa matokeo ambayo nilizungumza mwanzoni mwa kifungu.

Kutoa takwimu ni ngumu na kile nilichomaliza mbili mitandao ya neural: moja ilitoa asilimia kubwa ya utambuzi, na nyingine - kosa ndogo. Hapa ninawasilisha matokeo ya kwanza.

Kwa jumla, kama nilivyosema mara nyingi, kulikuwa na picha 100 kwenye testset. Kati ya hizi, 20 zilitambuliwa kwa mafanikio, 80 hazikufaulu, na kosa lilikuwa herufi 1.91 kwa kila picha. Ni mbaya zaidi kuliko waendeshaji wengine wote, lakini CAPTCHA pia inatii.

Badala ya hitimisho

Nilichapisha kila kitu kinachohusiana na kazi hii kwenye safu maalum ya jukwaa kwenye wavuti yangu, haswa: nambari ya chanzo, Netsukuku). Wakati huo huo, nataka kitu ambacho, kwanza, kinaweza kufanywa kwa mwaka (angalau na watu wawili), na pili, kitahitimu sana kwa nafasi ya juu katika ISEF sawa. Labda unaweza kupendekeza nielekee mwelekeo gani?

Niliamua kujua Python kidogo, lakini kufahamu "sio PHP tu" haipendezi. Maslahi ya ubinafsi yamekuwa suluhisha kiotomatiki Captcha Python.

Jambo lilianza na chapisho kutoka kwa Habr kutoka 2012 (maktaba ya picha kwa ujumla kutoka 2009).
Kanuni: https://habrahabr.ru/post/149091/

Nina 2.7.10 nje ya boksi, lakini nambari iliandikwa chini ya 2.5 (pamoja na PIL). Wanaandika kwamba inaendesha kikamilifu kwenye 2.7.3.

PIL ilizungushwa hivi
Kanuni: #pakua
curl -O -L http://effbot.org/media/downloads/Imaging-1.1.7.tar.gz
# dondoo
tar -xzf Imaging-1.1.7.tar.gz
Picha za cd-1.1.7
# jenga na usakinishe
python setup.py build
sudo python setup.py install
# au usanikishe kwa ajili yako tu bila kuhitaji ruhusa za msimamizi:
# python setup.py install --user

Kisha niliingiza moduli kama hii

Msimbo: #andika kwenye kiweko
chatu
#mkalimani atakayeamriwa atawashwa
kuagiza PIL
#ikiwa kila kitu kiko sawa, bonyeza Ctrl+D ili kuondoka

Nyoka sio rafiki na alfabeti ya Kicyrillic, niliongeza ujenzi mwanzoni mwa faili (ili iweze kutoa maoni juu ya ufundi katika Cyrillic)
Msimbo: # -*- usimbaji: utf-8 -*-

Hapa kuna baiskeli yenyewe (sijui jinsi ya kuandika mizunguko na sijui jinsi ya eval, kwa hivyo nilibadilisha vitu vingi kwa mkono).

Msimbo: # -*- usimbaji: utf-8 -*-
#ujinga huu unahitajika kwa alama za Kirusi

kutoka kwa Picha ya uingizaji ya PIL

kutoka kwa opereta kuagiza itemgetter


im = im.convert("P")
yake = im.histogram()
maadili = ()

kwa i katika safu (256):
maadili[i] = yake[i]

kwa j,k katika sorted(values.items(), key=itemgetter(1), reverse=True)[:15]:
chapisha "au pix ==",j#,k

#variable j huhifadhi rangi kumi maarufu zaidi

kutoka kwa Picha ya uingizaji ya PIL

im = Image.open("captcha.gif")
im = im.convert("P")

im = im.convert("P")

kwa x katika masafa (im.size):
kwa y katika masafa (im.size):
pix = im.getpixel((y,x))
temp = pix
#rangi hapa
im2.putpixel((y,x),0)

im2.save("output.gif")

#hapa inaonekana kama kila kitu kinaanza tangu mwanzo tena

kutoka kwa Picha ya uingizaji ya PIL

im = Image.open("output.gif")
im = im.convert("P")
im2 = Image.new("P", im.size,255)

im = im.convert("P")

kwa x katika masafa (im.size):
kwa y katika masafa (im.size):
pix = im.getpixel((y,x))
temp = pix
if pix == 255: # hizi ndio nambari za kupata
im2.putpixel((y,x),0)

nambari # mpya inaanzia hapa

herufi = Uongo
barua ya kupatikana=Uongo
kuanza = 0
mwisho = 0


pix = im2.getpixel((y,x))
ikiwa pix != 255:
herufi = Kweli
barua ya kupatikana = Kweli
kuanza = y


barua kupatikana = Uongo
mwisho = y
herufi.ongeza((anza,mwisho))

Barua=Uongo
chapisha barua

#nani anajua

darasa VectorLinganisha:
def ukubwa (binafsi, concordance):
jumla = 0
kwa neno,hesabu katika concordance.iteritems():
jumla += hesabu ** 2
rudisha hisabati.sqrt(jumla)

Uhusiano wa Def(binafsi, concordance1, concordance2):
umuhimu = 0
thamani ya juu = 0
kwa neno, hesabu katika konkodansi1.iteritems():
ikiwa concordance2.has_key(neno):
thamani ya juu += hesabu * concordance2
rudisha thamani ya juu / (self.magnitude(concordance1) * self.magnitude(concordance2))

#seti ya wahusika

kutoka kwa Picha ya uingizaji ya PIL
kuagiza hahlib
muda wa kuagiza

im = Image.open("captcha.gif")
im2 = Image.new("P", im.size,255)
im = im.convert("P")

chapisha im.histogram()

kwa x katika masafa (im.size):
kwa y katika masafa (im.size):
pix = im.getpixel((y,x))
temp = pix
#rangi hapa
ikiwa pix == 187 au pix == 224 au pix == 188 au pix == 223 au pix == 145 au pix == 151 au pix == 181 au pix == 144 au pix == 225 au pix == 182 au pix == 189 au pix == 12 au pix == 17 au pix == 139 au pix == 152: # au pix ==
im2.putpixel((y,x),0)

herufi = Uongo
barua ya kupatikana=Uongo
kuanza = 0
mwisho = 0

kwa y katika masafa (im2.size): # kipande kote
kwa x katika anuwai (im2.size): # kata chini
pix = im2.getpixel((y,x))
#hapa haikuwa "sawa na 255" yaani "haikuwa sawa na nyeupe"
ikiwa pix == 255:
herufi = Kweli

Ikipatikana herufi == Si kweli na herufi == Kweli:
barua ya kupatikana = Kweli
kuanza = y

Ikiwa herufi imepatikana == Kweli na herufi == Si kweli:
barua kupatikana = Uongo
mwisho = y
herufi.ongeza((anza,mwisho))
herufi=Uongo

# Nambari mpya iko hapa. Tunatoa kila picha na kuihifadhi kwenye diski nayo
# jina ambalo tunatumaini ni la kipekee

hesabu = 0
kwa barua kwa barua:
m = hahlib.md5()
im3 = im2.crop((barua, 0, herufi,im2.size))
m.sasisha("%s%s"%(time.time(),hesabu))
im3.save("./%s.gif"%(m.hexdigest()))
hesabu += 1

Kanuni ya operesheni ni hii: fanya histogram, uondoe vivuli vya kawaida zaidi, uhifadhi wengine katika rangi nyeusi na nyeupe, ugawanye pamoja na mipaka ya alama, kulinganisha alama na sampuli.

Captcha ya asili, bila vivuli 10 maarufu, bila vivuli 15 maarufu (sikuivunja kwa alama - kwa sababu kuna ishara isiyo kamili).

Captcha ya asili, bila vivuli 15 maarufu, imegawanywa katika wahusika 2 (chafu kidogo).

Inawezekana kabisa kufunga solver chini ya captcha rahisi. Tunahitaji maeneo ya kuvutia yenye captcha rahisi kwa ajili ya kumalizia na kujaribu.

Siku njema! Hivi majuzi, kwa mahitaji fulani, captcha katika Python ilihitajika kutoka kwa watu "wadadisi". Niliangalia Google na hakuna kitu cha kawaida bila Django Sikuiona. Kama matokeo, nilifikia hitimisho kwamba sitaiandika kama tofauti WSGI maombi, lakini kwa urahisi CGI hati.

Kifurushi kilichochaguliwa kwa kufanya kazi na picha kilikuwa Maktaba ya Picha ya Python. Kwa bahati mbaya, PIL hutoa uwezo mdogo ikilinganishwa na GD2 katika PHP.

Unaweza kupakua kifurushi cha matoleo ya Python 2 na 3 kutoka hapa: http://www.lfd.uci.edu/~gohlke/pythonlibs/

Ningependa kusema mara moja kwamba inatumika Chatu 3.1, ingawa nadhani itaendesha pia kwenye Python 2.6+.

Na hivyo, mwisho tunapaswa kupata kizazi cha picha cha wahusika 5-6 kwenye historia ya rangi nyingi.

Kwa kuwa sichapishi kumbukumbu na kila kitu tayari hapa, tutafanya kila kitu kulingana na mwongozo.

Saraka na uongozi wao:

Cgi-bin
--kamata
--asili
--fonti
--index.py

Nadhani ni wazi kuwa kwenye folda ya cgi-bin kuna folda ya captcha ambayo asili na fonti na hati ya index.py yenyewe ziko.

Sasa tunahitaji asili. Tunaandika "asili" kwenye Google.Picha na kupakua vipande 15-20. Na unahitaji kufanya mistatili kama hiyo kupima 200x60 px katika umbizo JPEG.

Tunatupa kila kitu kwenye folda ya asili.

Sasa fonti. Tunavutiwa TrueType fonti (*.ttf). Tunachukua fonti 15 za ujanja na kuzitupa kwenye folda ya fonti.

Asili zote zipo, fonti zipo, sasa index.py yenyewe.

Chapisha ("Aina ya Yaliyomo: picha/jpeg"); chapisha (""); agiza sys, os, re, nasibu kutoka kwa PIL kuleta Picha, ImageFont, ImageDraw darasa captcha(kitu): def __init__(self): self.string = ""; self.root = os.getcwd(); self.path_backgrounds = self.root+"/backgrounds/"; self.path_fonts = self.root+"/fonts/"; def gen_string(self): chars = ("a", "b", "d", "e", "f", "g", "h", "j", "m", "n", " q", "r", "t", "u", "y", "A", "B", "D", "E", "F", "G", "H", "J" , "M", "N", "Q", "R", "T", "U", "Y", "1", "2", "3", "4", "5", " 6", "7", "8", "9"); kwa i katika anuwai(random.randint(5, 6)): self.string += chars; kurudi self.string; def gen_backgrounds(binafsi): picha =; ikiwa os.path.exists(self.path_backgrounds): kwa f in os.listdir(self.path_backgrounds): if os.path.isdir(self.path_backgrounds+"/"+f): endelea; if re.search("\.(jpeg|jpg)$", f, re.IGNORECASE): images.append(self.path_backgrounds+"/"+f); kingine: sys.toka (); ikiwa len(picha) == 0: sys.toka(); kurudi picha; def gen_fonts(binafsi): fonti = ; ikiwa os.path.exists(self.path_fonts): kwa f in os.listdir(self.path_fonts): if os.path.isdir(self.path_fonts+"/"+f): endelea; ukitafuta upya("\.(ttf)$", f, re.IGNORECASE): fonts.append(self.path_fonts+"/"+f); lingine: sys.exit(); ikiwa len(fonti) == 0: sys.toka (); fonti za kurudi; def gen_image(binafsi): string = self.gen_string(); asili = self.gen_backgrounds(); fonti = self.gen_fonts(); picha = Picha.mpya("RGB", (200,60), "#FFF") chora = ImageDraw.Chora(picha); kwa i katika masafa(5): usuli = Image.open(asili); x = nasibu.randint(0, 160); cp = background.crop((x, 0, x+40, 60)); picha.bandika(cp, (i*40, 0)); ikiwa len(kamba) == 5: x = random.randint (25, 30); kingine: x = random.randint (8, 11); kwa char katika kamba: font = fonts; y = nasibu.randint (5, 25); font_size = random.randint (24, 30); color_dark = "rgb("+str(random.randint(0,150))+","+str(random.randint(0,100))+","+str(random.randint(0,150))+""; color_font = "rgb("+str(random.randint(50,200))+","+str(random.randint(0,150))+","+str(random.randint(50,200))+""; ttf = ImageFont.truetype(font, font_size) draw.text((x+1, y+1), char, fill=color_dark, font=ttf) draw.text((x, y), char, fill=color_font, font=ttf) x += random.randint(13, 15) + 18; image.save(sys.stdout, "JPEG") cp = captcha(); cp.gen_image(); #cp.string; kamba ya tabia

Ni hayo tu. Nina picha iliyotolewa katika http://localhost/cgi-bin/captcha/index.py. Ifuatayo, unaweza kuongeza utaratibu wa kuhifadhi kwa kamba iliyotolewa ( cp.kamba) kutoka kwa vikao au mahali pengine.

Kuna njia tofauti za kukwepa CAPTCHA zinazolinda tovuti. Kwanza, kuna huduma maalum zinazotumia kazi ya mikono kwa bei nafuu na kutoa kutatua captcha 1000 kwa $1 halisi. Kama mbadala, unaweza kujaribu kuandika mfumo wa akili ambao, kwa kutumia algorithms fulani, utafanya utambuzi yenyewe. Mwisho sasa unaweza kutekelezwa kwa kutumia matumizi maalum.

Tatua CAPTCHA

Kutambua CAPTCHA mara nyingi ni kazi isiyo ya kawaida. Ni muhimu kutumia filters nyingi tofauti kwenye picha ili kuondoa uharibifu na kelele, ambayo watengenezaji wanataka kutumia ili kuimarisha ulinzi. Mara nyingi lazima utekeleze mfumo wa kujifunza kulingana na mitandao ya neural (hii, kwa njia, sio ngumu kama inavyoweza kuonekana) ili kufikia matokeo yanayokubalika katika utatuzi wa kiotomatiki wa captcha. Ili kuelewa ninachozungumzia, ni bora kufungua kumbukumbu na kusoma makala nzuri "Cracking CAPTCHA: nadharia na mazoezi. Hebu tujue jinsi captchas zimevunjwa" na "Hebu tuangalie na kutambua. Kuvinjari vichujio vya Captcha" kutoka nambari #135 na #126, mtawalia. Leo nataka kukuambia juu ya maendeleo ya TesserCap, ambayo mwandishi anaiita kisuluhishi cha CAPTCHA cha ulimwengu wote. Jambo la kushangaza, chochote ambacho mtu anaweza kusema.

Kwanza angalia TesserCap

Mwandishi wa programu hiyo alifanya nini? Aliangalia jinsi tatizo la utatuzi wa kiotomatiki wa CAPTCHA kawaida hushughulikiwa na kujaribu kufupisha uzoefu huu katika zana moja. Mwandishi aligundua kuwa kuondoa kelele kutoka kwa picha, ambayo ni, kutatua shida ngumu zaidi katika kutambua captchas, vichungi sawa hutumiwa mara nyingi. Inabadilika kuwa ikiwa unatumia zana inayofaa ambayo hukuruhusu kutumia vichungi kwa picha bila mabadiliko magumu ya hesabu, na kuchanganya na mfumo wa OCR wa utambuzi wa maandishi, unaweza kupata programu inayoweza kufanya kazi kabisa. Hii, kwa kweli, ni nini Gursev Singh Kalra kutoka McAfee alifanya. Kwa nini hili lilihitajika? Mwandishi wa shirika aliamua kuangalia kwa njia hii jinsi captchas salama za rasilimali kubwa zilivyo. Kwa ajili ya majaribio, tulichagua tovuti hizo za Intaneti ambazo zinatembelewa zaidi kulingana na huduma inayojulikana ya takwimu. Watahiniwa wa kushiriki katika majaribio walijumuisha viumbe vikali kama vile Wikipedia, eBay, na mtoa huduma wa captcha reCaptcha. Ikiwa tunazingatia kwa ujumla kanuni ya uendeshaji wa programu, ni rahisi sana. Captcha ya awali huingia kwenye mfumo wa usindikaji wa awali wa picha, ambayo husafisha captcha kutoka kwa kelele yoyote na uharibifu na kuhamisha picha inayotokana na conveyor kwenye mfumo wa OCR, ambayo inajaribu kutambua maandishi juu yake. TesserCap ina kiolesura shirikishi cha picha na ina sifa zifuatazo:
  1. Ina mfumo wa uchakataji wa awali wa picha ambao unaweza kusanidiwa kwa kila captcha ya kibinafsi.
  2. Inajumuisha injini ya utambuzi ya Tesseract, ambayo hutoa maandishi kutoka kwa picha iliyochanganuliwa awali na iliyotayarishwa ya CAPTCHA.
  3. Inasaidia matumizi ya usimbaji mbalimbali katika mfumo wa utambuzi.
Nadhani maana ya jumla ni wazi, kwa hivyo ninapendekeza uone jinsi inavyoonekana. Usanifu wa matumizi haukuweza lakini kusababisha ugumu wa kiolesura chake, kwa hivyo dirisha la programu linaweza kusababisha kusinzia kidogo. Kwa hiyo, kabla ya kuhamia moja kwa moja kwa kutambua captchas, ninapendekeza uelewe kiolesura chake na utendaji uliojengwa ndani.
Uchakataji na uchimbaji wa picha
maandishi kutoka kwa captcha

Kuhusu

Hatukuweza kujizuia kusema angalau maneno machache kuhusu mwandishi wa shirika la ajabu la TesserCap. Jina lake ni Gursev Singh Kalra. Yeye ni mshauri mkuu wa kitengo cha huduma za kitaalamu cha Foundstone, sehemu ya McAfee. Gursev amezungumza kwenye mikutano kama vile ToorCon, NullCon na ClubHack. Yeye ndiye mwandishi wa zana za TesserCap na SSLSmart. Kwa kuongezea, alitengeneza zana kadhaa kwa mahitaji ya ndani ya kampuni. Lugha pendwa za programu ni Ruby, Ruby on Rails na C#. Kitengo cha huduma za kitaalamu cha Foundstone®, anakofanya kazi, huyapa mashirika huduma na mafunzo ya kitaalamu ili kuhakikisha kuwa mali zao zinalindwa kwa uthabiti na kwa ufanisi dhidi ya matishio magumu zaidi. Timu ya Huduma za Kitaalamu ina wataalam wanaotambulika wa usalama na wasanidi programu walio na uzoefu mkubwa wa kufanya kazi na mashirika ya kimataifa na mashirika ya serikali.

Kiolesura. Kichupo kikuu

Baada ya kuzindua programu, tunawasilishwa na dirisha na tabo tatu: Kuu, Chaguzi, Utayarishaji wa Picha. Kichupo kikuu kina vidhibiti vinavyotumika kuanzisha na kusimamisha jaribio la picha la CAPTCHA, kutoa takwimu za majaribio (ni ngapi zinazokisiwa na ni ngapi hazijakisiwa), vinjari na uchague picha kwa ajili ya kuchakata mapema. Sehemu ya ingizo ya URL (kidhibiti #1) lazima iwe na URL kamili ambayo programu ya wavuti hutumia kupata captcha. URL inaweza kupatikana kwa kubofya upande wa kulia wa picha ya CAPTCHA, kunakili au kutazama msimbo wa ukurasa, na kutoa URL kutoka kwa sifa ya src ya lebo ya picha ..site/common/rateit/captcha.asp?. Karibu na mstari wa anwani kuna kipengele kinachobainisha idadi ya captcha zinazohitaji kupakuliwa kwa ajili ya majaribio. Kwa kuwa programu inaweza tu kuonyesha picha 12 kwa wakati mmoja, inatoa vidhibiti vya kuvinjari kwa ukurasa kwa ukurasa wa captcha zilizopakuliwa. Kwa hivyo, wakati wa majaribio ya kiwango kikubwa, tutaweza kuvinjari captcha zilizopakuliwa na kutazama matokeo ya utambuzi wao. Vifungo vya Anza na Sitisha huanza na kusimamisha majaribio, mtawaliwa. Baada ya kupima, unahitaji kutathmini matokeo ya utambuzi wa picha, kuashiria kila mmoja wao kuwa sahihi au sahihi. Naam, kazi ya mwisho, muhimu zaidi hutumikia kuhamisha picha yoyote kwenye mfumo wa usindikaji wa awali, ambapo chujio kinawekwa ambacho huondoa kelele na uharibifu kutoka kwa picha. Ili kutuma picha kwa mfumo wa usindikaji, bonyeza-kulia kwenye picha inayotaka na uchague Tuma kwa Kitayarisha Picha kutoka kwa menyu ya muktadha.

Kiolesura. Kichupo cha Chaguo

Kichupo cha Chaguo kina vidhibiti mbalimbali vya kusanidi TesserCap. Hapa unaweza kuchagua mfumo wa OCR, kuweka vigezo vya wakala wa wavuti, kuwezesha uelekezaji upya wa picha na usindikaji wa awali, ongeza vichwa maalum vya HTTP, na pia ueleze anuwai ya herufi za mfumo wa utambuzi: nambari, herufi ndogo, herufi kubwa, herufi maalum. Sasa kuhusu kila chaguo kwa undani zaidi. Kwanza kabisa, unaweza kuchagua mfumo wa OCR. Kwa chaguo-msingi, ni moja tu inayopatikana - Tesseract-ORC, kwa hivyo huna haja ya kujisumbua na chaguo hapa. Kipengele kingine cha kuvutia sana cha programu ni kuchagua aina mbalimbali za wahusika. Hebu tuchukue, kwa mfano, captcha kutoka kwenye tovuti - ni wazi kwamba haina barua moja, lakini inajumuisha namba tu. Kwa hivyo kwa nini tunahitaji herufi za ziada ambazo zitaongeza tu uwezekano wa utambuzi usio sahihi? Lakini vipi ikiwa unachagua Kesi ya Juu? Je, programu itaweza kutambua captcha inayojumuisha herufi kubwa za lugha yoyote? Hapana, hawezi. Programu inachukua orodha ya herufi zinazotumiwa kutambuliwa kutoka kwa faili za usanidi zilizo katika \Program Files\Foundstone Free Tools\TesserCap 1.0\tessdata\configs. Acha nieleze kwa mfano: ikiwa tulichagua chaguzi za Nambari na Kesi ya Chini, programu itafikia faili ya nambari ya chini, kuanzia na parameta ya testsedit. char orodha nyeupe. Hii inafuatwa na orodha ya wahusika ambayo itatumika kutatua captcha. Kwa chaguo-msingi, faili zina herufi za alfabeti ya Kilatini pekee, kwa hivyo ili kutambua alfabeti ya Cyrilli unahitaji kubadilisha au kuongeza orodha ya herufi. Sasa kidogo juu ya kile sehemu ya Vichwa vya Ombi la Http inahitajika. Kwa mfano, kwenye tovuti fulani unahitaji kuingia ili kuona captcha. Ili TesserCap ifikie kinasa, programu inahitaji kupitisha vichwa kama vile Kubali, Cookie na Referrer, n.k. katika ombi la HTTP Kwa kutumia proksi ya wavuti (Fiddler, Burp, Charles, WebScarab, Paros, n.k.), wewe inaweza kukatiza vichwa vya ombi vinavyotumwa na kuviingiza kwenye sehemu ya ingizo ya Vichwa vya Ombi la Http. Chaguo jingine ambalo hakika litakuja kwa manufaa ni Fuata Uelekezaji Upya. Jambo ni kwamba TesserCap haifuati uelekezaji upya kwa chaguo-msingi. Ikiwa URL ya jaribio inahitaji kufuata uelekezaji kwingine ili kupata picha, unahitaji kuchagua chaguo hili. Kweli, kuna chaguo moja la mwisho lililosalia, kuwezesha / kulemaza utaratibu wa uchakataji wa picha, ambao tutazingatia zaidi. Kwa chaguo-msingi, usindikaji wa awali wa picha umezimwa. Watumiaji kwanza husanidi vichujio vya kuchakata picha kulingana na picha za CAPTCHA zinazojaribiwa na kisha kuwezesha moduli hii. Picha zote za CAPTCHA zinazopakiwa baada ya kuwezesha chaguo la Wezesha Uchakataji wa Picha huchakatwa awali na kisha kutumwa kwa mfumo wa Tesseract OCR kwa ajili ya kutoa maandishi.

Kiolesura. Kichupo cha Kuchakata Picha

Naam, tumefikia kichupo cha kuvutia zaidi. Hapa ndipo vichujio husanidiwa ili kuondoa kelele na ukungu mbalimbali kutoka kwa captcha, ambazo hujaribu kutatiza kazi ya mfumo wa utambuzi iwezekanavyo. Mchakato wa kusanidi kichujio cha ulimwengu wote ni rahisi sana na una hatua tisa. Katika kila hatua ya usindikaji wa awali wa picha, mabadiliko kwenye picha yanaonyeshwa. Kwa kuongeza, ukurasa una sehemu ya uthibitishaji ambayo inakuwezesha kutathmini usahihi wa utambuzi wa captcha wakati kichujio kinatumiwa. Hebu tuangalie kila hatua kwa undani. Hatua ya 1. Ubadilishaji wa rangi Katika hatua hii, rangi za pikseli za picha za CAPTCHA zinageuzwa. Msimbo ulio hapa chini unaonyesha jinsi hii inavyotokea: kwa (kila pikseli katika CAPTCHA) ( ikiwa (invertRed ni kweli) nyekundu mpya = 255 - nyekundu ya sasa ikiwa (invertBlue ni kweli) bluu mpya = 255 - bluu ya sasa ikiwa (invertGreen ni kweli ) kijani kipya = 255 – kijani kibichi ) Kugeuza rangi moja au zaidi mara nyingi hufungua uwezekano mpya wa kuthibitisha picha ya CAPTCHA inayojaribiwa. Hatua ya 2. Mabadiliko ya rangi Katika hatua hii, unaweza kubadilisha vipengele vya rangi kwa saizi zote kwenye picha. Kila sehemu ya nambari inaweza kuwa na thamani zinazowezekana 257 (−1 hadi 255). Kwa vipengele vya RGB vya kila pixel, kulingana na thamani katika uwanja, vitendo vifuatavyo vinafanywa:
  1. Ikiwa thamani ni -1, sehemu ya rangi inayolingana haibadilika.
  2. Ikiwa thamani sio -1, vipengele vyote vilivyopatikana vya rangi maalum (nyekundu, kijani au bluu) hubadilika kulingana na thamani iliyoingia kwenye sehemu. Thamani ya 0 huondoa sehemu, thamani ya 255 huweka kiwango chake cha juu, nk.
Hatua ya 3: Kijivu (Kijivu) Katika hatua ya tatu, picha zote zinabadilishwa kuwa picha za kijivu. Hii ndiyo hatua pekee ya lazima katika ubadilishaji wa picha ambayo haiwezi kurukwa. Kulingana na kitufe kilichochaguliwa, moja ya vitendo vifuatavyo hufanywa vinavyohusiana na sehemu ya rangi ya kila pikseli:
  1. Wastani -> (Nyekundu + Kijani + Bluu)/3.
  2. Binadamu -> (0.21 * Nyekundu + 0.71 * Kijani + 0.07 * Bluu).
  3. Wastani wa vipengele vya rangi vya chini na vya juu zaidi -> (Kima cha chini kabisa (Nyekundu + Kijani + Bluu) + Upeo (Nyekundu + Kijani + Bluu))/2.
  4. Kima cha chini kabisa -> Kima cha chini (Nyekundu + Kijani + Bluu).
  5. Upeo -> Upeo (Nyekundu + Kijani + Bluu).
Kulingana na ukubwa na usambazaji wa kijenzi cha rangi cha CAPTCHA, kichujio chochote kati ya hivi kinaweza kuboresha picha iliyotolewa kwa uchakataji zaidi.
Hatua ya 4: Kulainisha na Kunoa Ili kuifanya iwe vigumu zaidi kutoa maandishi kutoka kwa picha za CAPTCHA, kelele huongezwa kwao kwa njia ya vitone vya pikseli moja na nyingi, mistari ya nje, na upotoshaji wa anga. Picha inapolainishwa, kelele nasibu huongezeka, ambayo huondolewa kwa kutumia Bucket au Cutoff filters. Katika sehemu ya nambari ya Pasi, unapaswa kuonyesha ni mara ngapi unahitaji kutumia mask inayolingana ya picha kabla ya kuhamia hatua inayofuata. Hebu tuangalie vipengele vya chujio vya kupinga-aliasing na kunoa. Aina mbili za masks ya picha zinapatikana:
  1. Masks zisizohamishika. Kwa chaguo-msingi, TesserCap ina vinyago sita vya picha maarufu zaidi. Masks haya yanaweza kulainisha picha au kuinoa (Laplace transform). Mabadiliko yanaonyeshwa mara baada ya kuchagua mask kwa kutumia vifungo vinavyolingana.
  2. Vinyago vya picha maalum. Mtumiaji pia anaweza kusanidi vinyago maalum vya usindikaji wa picha kwa kuingiza maadili katika sehemu za nambari na kubofya kitufe cha Hifadhi Mask. ikiwa jumla ya coefficients katika madirisha haya ni chini ya sifuri, hitilafu hutolewa na mask haitumiki. Ikiwa unachagua mask iliyopangwa, huna haja ya kutumia kitufe cha Hifadhi Mask.
Hatua ya 5. Kuanzisha vivuli vya kijivu Katika hatua hii ya usindikaji wa picha, saizi zake zinaweza kupakwa rangi katika vivuli vingi vya kijivu. Kichujio hiki kinaonyesha mgawanyo wa kijivu wa ndoo 20/safu. Asilimia ya saizi zilizopakwa rangi ya vivuli vya kijivu katika safu kutoka 0 hadi 12 imebainishwa kwenye ndoo 0, asilimia ya saizi zilizopakwa rangi ya kijivu katika safu kutoka 13 hadi 25 imebainishwa kwenye ndoo 1, nk. Mtumiaji anaweza Kuchagua. mojawapo ya yafuatayo kwa kila masafa ya rangi ya kijivu:
  1. Ondoka Kama Ilivyo.
  2. Badilisha na Nyeupe.
  3. Badilisha na nyeusi.
Kwa chaguo hizi, unaweza kudhibiti safu tofauti za rangi ya kijivu na kupunguza/kuondoa kelele kwa kubadilisha rangi ya kijivu kuwa nyeupe au nyeusi. Hatua ya 6. Kuweka cutoff Kichujio hiki hupanga utegemezi wa kiwango cha kijivu kwenye marudio ya kutokea na hukuhimiza kuchagua sehemu ya kukata. Kanuni ya uendeshaji wa kichujio cha kukata imeonyeshwa hapa chini katika pseudocode: ikiwa (thamani ya rangi ya kijivu ya pixel<= Cutoff) pixel grayscale value = (0 OR 255) ->kulingana na chaguo gani limechaguliwa (<= или =>: Weka Kila Pixel kwa thamani<=/=>Kizingiti hadi 0. Imesalia hadi 255) Grafu inaonyesha usambazaji wa kina wa pikseli za CAPTCHA kulingana na rangi na husaidia kuondoa kelele kwa kupunguza kiwango cha kijivu. Hatua ya 7: kukata Baada ya kuweka kulainisha, kukata, ndoo na vichujio vingine, picha za CAPTCHA bado zinaweza kuwa na kelele kwa kutumia vitone vya pikseli moja au nyingi, mistari iliyopotea na vizalia vya anga. Kanuni ya kichujio cha kunakili ni kama ifuatavyo: ikiwa idadi ya saizi zilizo karibu zilizopakwa rangi ya kijivu ni chini ya thamani katika sehemu ya nambari, kichujio cha kunakili huwapa thamani ya 0 (nyeusi) au 255 (nyeupe). kwa chaguo la mtumiaji. Katika kesi hii, CAPTCHA inachambuliwa kwa usawa na wima. Hatua ya 8: Kubadilisha Upana wa Mpaka Kwa mujibu wa mwandishi wa shirika hilo, wakati wa utafiti wa awali na maendeleo ya TesserCap, alibainisha mara kwa mara kwamba wakati picha za CAPTCHA zina mstari wa mpaka wa nene na rangi yake ni tofauti na historia kuu ya CAPTCHA, baadhi ya mifumo ya OCR haiwezi kutambua maandishi. Kichujio hiki kimeundwa kuchakata mistari ya mipaka na kuibadilisha. Mistari ya mipaka yenye upana uliobainishwa katika sehemu ya nambari hupakwa rangi nyeusi au nyeupe kwa hiari ya mtumiaji. Hatua ya 9: Ubadilishaji wa Kijivu Kichujio hiki hupitia kila pikseli na kubadilisha thamani yake ya kiwango cha kijivu na mpya, kama inavyoonyeshwa kwenye msimbo bandia ulio hapa chini. Ubadilishaji wa kijivu unafanywa ili kurekebisha picha kwa mipangilio ya rangi ya mfumo wa OCR. kwa (kila pikseli katika CAPTCHA) thamani mpya ya kijivujivu = 255 - thamani ya sasa ya kijivujivu Hatua ya 10: Kujaribu utambuzi wa captcha Madhumuni ya hatua hii ni kuhamisha picha iliyochakatwa awali ya CAPTCHA kwenye mfumo wa OCR ili iweze kutambuliwa. Kitufe cha Tatua huchukua picha baada ya kichujio cha kubadilisha rangi ya kijivu, kuituma kwa mfumo wa OCR ili kutoa maandishi, na kuonyesha maandishi yaliyorejeshwa kwenye GUI. Ikiwa maandishi yanayotambuliwa yanalingana na maandishi kwenye captcha, inamaanisha kuwa tumeweka kichujio kwa usahihi kwa usindikaji wa awali. Sasa unaweza kwenda kwenye kichupo cha chaguo na kuwezesha chaguo la Wezesha Uchakataji wa Picha ili kuchakata kapcha zote zilizopakuliwa zinazofuata.

Tambua captcha

Kweli, labda tumezingatia chaguzi zote za matumizi haya, na sasa itakuwa nzuri kujaribu captcha fulani kwa nguvu.
Matokeo ya tovuti ya uchanganuzi wa kinasa na ya awali
usindikaji wa picha. Kwa kuzingatia matokeo, chujio
Haikuweza kuipata Kwa hivyo, hebu tuzindue matumizi na tuende kwenye tovuti ya gazeti. Tunaona orodha ya habari za hivi punde, nenda kwa ile ya kwanza tunayokutana nayo na usogeze hadi mahali unapoweza kuacha maoni yako. Ndio, sio rahisi sana kuongeza maoni (bila shaka, vinginevyo wangekuwa wametupa kila kitu muda mrefu uliopita) - unahitaji kuingiza captcha. Kweli, wacha tuangalie ikiwa hii inaweza kuwa otomatiki. Nakili URL ya picha na ubandike kwenye upau wa anwani wa TesserCap. Tunaonyesha kwamba unahitaji kupakua captcha 12 na ubofye Anza. Mpango huo kwa utii ulipakia picha 12 na kujaribu kuzitambua. Kwa bahati mbaya, captcha zote hazikutambuliwa, kama inavyothibitishwa na maandishi -Imeshindwa- chini yao, au zilitambuliwa vibaya. Kwa ujumla, hii haishangazi, kwani kelele za nje na upotoshaji haukuondolewa. Hivi ndivyo tutafanya sasa. Bofya kulia kwenye mojawapo ya picha 12 zilizopakiwa na uitume kwa mfumo wa usindikaji wa awali (Tuma Kwa Kitayarisha Picha). Baada ya kuchunguza kwa makini captcha zote 12, tunaona kwamba zina nambari pekee, kwa hiyo tunaenda kwenye kichupo cha chaguo na kuonyesha kwamba nambari pekee zinahitajika kutambuliwa (Seti ya Tabia = Nambari). Sasa unaweza kwenda kwenye kichupo cha Kutayarisha Picha ili kusanidi vichujio. Nitasema mara moja kwamba baada ya kucheza na vichungi vitatu vya kwanza ("Ubadilishaji wa Rangi", "Mabadiliko ya Rangi", "Grad Gradation") sikuona athari yoyote nzuri, kwa hiyo niliacha kila kitu pale kwa default. Nilichagua Smooth Mask 2 na kuweka idadi ya kupita kwa moja. Niliruka kichujio cha ndoo za Grayscale na kwenda moja kwa moja kwa mipangilio ya kunakili. Nilichagua thamani 154 na nilionyesha kuwa saizi hizo ambazo ni ndogo zinapaswa kuwekwa kwa 0, na zile ambazo ni kubwa zaidi zinapaswa kuwekwa 255. Ili kuondokana na saizi zilizobaki, niliwezesha kukata na kubadilisha upana wa mpaka hadi 10. haikuwa maana kuwezesha kichujio cha mwisho, kwa hivyo nilibofya mara moja Suluhisha. Kwenye captcha nilikuwa na nambari 714945, lakini programu iliitambua kama 711435. Hii, kama unaweza kuona, sio sahihi kabisa. Mwishowe, haijalishi nilijaribu sana, sikuweza kutambua captcha vizuri. Ilinibidi nijaribu pastebin.com, ambayo niliweza kutambua bila shida yoyote. Lakini ikiwa una bidii zaidi na mvumilivu na utaweza kupata captcha kutambuliwa kwa usahihi kutoka kwa tovuti, kisha nenda mara moja kwenye kichupo cha chaguo na uwashe Wezesha Uchakataji wa Picha. Kisha nenda kwa Kuu na, kwa kubofya Anza, pakua kundi jipya la captcha, ambalo sasa litachakatwa na kichujio chako. Baada ya programu kuendeshwa, weka alama kwenye vibao vinavyotambulika kwa usahihi/visivyo sahihi (Weka alama kuwa Sahihi/Tia alama kama vitufe visivyosahihi). Kuanzia sasa na kuendelea, unaweza kuona muhtasari wa takwimu za utambuzi kwa kutumia Onyesha Takwimu. Kwa ujumla, hii ni aina ya ripoti juu ya usalama wa CAPTCHA fulani. Ikiwa kuna swali kuhusu kuchagua suluhisho moja au nyingine, basi kwa msaada wa TesserCap inawezekana kabisa kufanya majaribio yako mwenyewe.

Matokeo ya ukaguzi wa CAPTCHA kwenye tovuti maarufu

Tovuti na asilimia ya captcha zinazotambulika:
  • Wikipedia > 20-30%
  • eBay > 20-30%
  • reddit.com > 20-30%
  • CNBC > 50%
  • foodnetwork.com > 80–90%
  • dailymail.co.uk > 30%
  • megaupload.com > 80%
  • pastebin.com > 70-80%
  • cavenue.com > 80%

Hitimisho

Picha za CAPTCHA ni mojawapo ya njia bora zaidi za kulinda programu za wavuti kutokana na kujaza fomu kiotomatiki. Hata hivyo, captcha dhaifu zitaweza kulinda dhidi ya roboti nasibu na hazitapinga majaribio yaliyolengwa ya kuzitatua. Kama algoriti za kriptografia, picha za CAPTCHA, ambazo zimejaribiwa kwa kina na kutoa kiwango cha juu cha usalama, ndizo njia bora zaidi za kujilinda. Kulingana na takwimu zilizotolewa na mwandishi wa programu, nilichagua reCaptcha kwa miradi yangu na nitaipendekeza kwa marafiki zangu wote - iligeuka kuwa sugu zaidi ya wale waliojaribiwa. Kwa hali yoyote, usisahau kwamba kuna huduma nyingi kwenye mtandao ambazo hutoa ufumbuzi wa CAPTCHA wa nusu otomatiki. Kupitia API maalum, unapitisha picha kwa huduma, na baada ya muda mfupi inarudi suluhisho. Mtu halisi (kwa mfano, kutoka Uchina) anatatua kinasa na analipwa senti nzuri kwa hiyo. Hakuna ulinzi tena hapa. 🙂