簡(jiǎn)單的驗(yàn)證碼識(shí)別OC

第一次接觸圖像解析,隨便上網(wǎng)搜羅了一些資料自己整理了一下就不要臉的寫了下來(lái),有錯(cuò)的地方還望指點(diǎn).

先說(shuō)說(shuō)大致流程吧
1.先將圖片進(jìn)行降噪
2.將降噪的圖片二值化
3.對(duì)二值化的圖片進(jìn)行劃分,分割出獨(dú)立的字符圖片
4.識(shí)別

這是一個(gè)驗(yàn)證碼

我的夢(mèng)想是做一個(gè)二維碼.png

一琅催、降噪
1.我拿來(lái)處理的驗(yàn)證碼本身格式很簡(jiǎn)單,所以我對(duì)圖片進(jìn)行了灰值化處理。
圖片本身是一個(gè)個(gè)像素點(diǎn)構(gòu)成蚌堵,可以將圖片看成是一個(gè)由像素構(gòu)成的二維數(shù)組芍秆。每個(gè)像素點(diǎn)都有Red Green Blue三個(gè)顏色的值个初,通過(guò)遍歷像素點(diǎn)乖菱,令R = G = B來(lái)完成圖片的灰值化坡锡。
常見的灰值化算法(方法?窒所?):
1.g(x,y) = (r(x帆锋,y) + g(x吵取,y) + b(x,y))/3
2.g(x锯厢,y) = 0.11r(x皮官,y) + 0.59g(x脯倒,y) + 0.3*b(x,y)
3.g(x捺氢,y) = min(min(r(x藻丢,y), g(x,y)) , b(x摄乒,y))

第二種算法是來(lái)源于NTSC色彩空間中Y分量的計(jì)算公式悠反,處理大部分驗(yàn)證碼效果比較滿意。但處理紅色調(diào)為主的驗(yàn)證碼就不行了馍佑,權(quán)值太小斋否。在我的案例里我選用的就是第二種算法,因?yàn)槲业膱D像真的簡(jiǎn)單:-D拭荤。

如果圖片有噪點(diǎn)還需要對(duì)噪點(diǎn)進(jìn)行判斷茵臭,具體操作是判斷某個(gè)像素點(diǎn)與周圍8個(gè)像素點(diǎn)的色差是否大于某個(gè)闕值,如果大于就+1s,如果有超過(guò)6個(gè)像素點(diǎn)大于的話就認(rèn)定位噪點(diǎn)舅世。周圍沒(méi)有8個(gè)點(diǎn)的一律剔除旦委,那些是邊界點(diǎn)。

灰值化.png

二雏亚、二值化
沒(méi)覺得二社证、二像一個(gè)表情?评凝?好了言歸正傳追葡,當(dāng)圖像進(jìn)行灰值化后通過(guò)計(jì)算閾值可以將圖片進(jìn)行二值化,低于閾值的g(x奕短,y)設(shè)為0宜肉,高于閾值的設(shè)為1...是255!0代表黑色翎碑,255代表白色谬返。雖然不準(zhǔn)確,但是比較好理解日杈。


二值化不要太清晰雖然本身就很清晰了.png

三遣铝、切分
這個(gè)我沒(méi)寫下去,我通過(guò)統(tǒng)計(jì)一條X軸上所有的黑色像素點(diǎn)來(lái)獲取字與字之間間隔的閾值莉擒。當(dāng)?shù)陀谶@個(gè)閾值或等于0時(shí)就可以認(rèn)為這是字與字之間的間隔酿炸,通過(guò)這個(gè)分割字符串。好像還有別的方法切分涨冀,具體應(yīng)該看是什么類型的驗(yàn)證碼填硕。

四、識(shí)別
我集成了TesserectORC進(jìn)行匹配,所以我切分也沒(méi)搞扁眯。大致還是記錄一下吧壮莹。目前的圖片在理想情況下會(huì)根據(jù)每個(gè)字符切成一塊矩陣。這個(gè)矩陣上0是空白1是有像素姻檀。一個(gè)圖片字符就轉(zhuǎn)換為了一個(gè)矩陣命满,然后用你的肉眼去識(shí)別它,做成鍵值對(duì)绣版,通過(guò)對(duì)比這個(gè)矩陣和另一個(gè)矩陣是否一致來(lái)確定另一個(gè)矩陣是不是這個(gè)字符胶台。什么漢明距離,編輯距離我也不太懂僵娃,就當(dāng)一個(gè)索引以后拓展概作。

五、TesserectORC
oc 上識(shí)別圖像用這個(gè)應(yīng)該沒(méi)錯(cuò)默怨,免費(fèi)而且有g(shù)oogle維護(hù)讯榕。

代碼

#import "UIImage+BGImage.h"
#import <TesseractOCR/TesseractOCR.h>

@implementation UIImage (BGImage)

typedef enum {
    
    ALPHA = 0,
    
    BLUE = 1,
    
    GREEN = 2,
    
    RED = 3
    
} PIXELS;

- (UIImage *)convertToGrayscale {
    
    CGSize size = [self size];
    
    int width = size.width;
    
    int height = size.height;
    
    
    //獲取像素點(diǎn)數(shù)組
    uint32_t *pixels = (uint32_t *) malloc(width * height * sizeof(uint32_t));
    
    memset(pixels, 0, width * height * sizeof(uint32_t));
    
    //創(chuàng)建顏色通道
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    //上下文規(guī)則?匙睹?我也不懂
    CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width * sizeof(uint32_t), colorSpace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedLast);
    
    //創(chuàng)建圖片上下文
    CGContextDrawImage(context, CGRectMake(0, 0, width, height), [self CGImage]);
    
    NSMutableArray *array = [NSMutableArray array];
    NSMutableArray *nub = [NSMutableArray array];
    for(int x = 0; x < width; x++) {
//        NSMutableString *str = [NSMutableString string];
        int i = 0;

        for(int y = 0; y < height; y++){
            
            uint8_t *rgbaPixel = (uint8_t *) &pixels[y * width + x];
            
            uint32_t gray = 0.11 * rgbaPixel[RED] + 0.59 * rgbaPixel[GREEN] + 0.3* rgbaPixel[BLUE];
//            uint32_t gray = MIN(MIN(rgbaPixel[RED], rgbaPixel[GREEN]), rgbaPixel[BLUE]);
//            uint32_t gray = rgbaPixel[GREEN];
            
            if (gray > 138) {
                gray = 255;
            }else {
                gray = 0;
                i++;
                //保存黑點(diǎn)的XY值
                NSValue *value = [NSValue valueWithCGPoint:CGPointMake(x, y)];
                [array addObject:value];
            }
            
            rgbaPixel[RED] = gray;
            
            rgbaPixel[GREEN] = gray;
            
            rgbaPixel[BLUE] = gray;
            
        }
        [nub addObject:[NSNumber numberWithInt:i]];
    }
//    NSLog(@"%@",nub);
////    NSLog(@"%@",array);
//    //i代表y值
//    for (int i = 0; i < nub.count; i++) {
//        NSNumber *num = nub[i];
//        if (num.intValue == 0) {
//            
//        }
//    }
    
    CGImageRef image = CGBitmapContextCreateImage(context);
    
    CGContextRelease(context);
    CGColorSpaceRelease(colorSpace);
    free(pixels);
    
    UIImage *resultUIImage = [UIImage imageWithCGImage:image];
    
    CGImageRelease(image);

    G8Tesseract *rect = [[G8Tesseract alloc]init];
    rect.language = @"eng";
    rect.engineMode = G8OCREngineModeTesseractCubeCombined;
    rect.pageSegmentationMode = G8PageSegmentationModeAuto;
    rect.maximumRecognitionTime = 60.0;
    rect.image = resultUIImage;
    NSString *newStr = rect.recognizedText;
    
    NSLog(@"hhhhh::%@",newStr);
    
    return resultUIImage;
    
}

@end

差不多就是這樣愚屁。能幫到需要的人一點(diǎn)點(diǎn)就好了。蟹蟹看完

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末痕檬,一起剝皮案震驚了整個(gè)濱河市霎槐,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌梦谜,老刑警劉巖丘跌,帶你破解...
    沈念sama閱讀 210,978評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異唁桩,居然都是意外死亡闭树,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,954評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門荒澡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)报辱,“玉大人,你說(shuō)我怎么就攤上這事单山“郑” “怎么了?”我有些...
    開封第一講書人閱讀 156,623評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵米奸,是天一觀的道長(zhǎng)昼接。 經(jīng)常有香客問(wèn)我,道長(zhǎng)躏升,這世上最難降的妖魔是什么辩棒? 我笑而不...
    開封第一講書人閱讀 56,324評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮膨疏,結(jié)果婚禮上一睁,老公的妹妹穿的比我還像新娘。我一直安慰自己佃却,他們只是感情好者吁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,390評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著饲帅,像睡著了一般复凳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上灶泵,一...
    開封第一講書人閱讀 49,741評(píng)論 1 289
  • 那天育八,我揣著相機(jī)與錄音,去河邊找鬼赦邻。 笑死髓棋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的惶洲。 我是一名探鬼主播按声,決...
    沈念sama閱讀 38,892評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼恬吕!你這毒婦竟也來(lái)了签则?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,655評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤铐料,失蹤者是張志新(化名)和其女友劉穎渐裂,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體钠惩,經(jīng)...
    沈念sama閱讀 44,104評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柒凉,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,451評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了妻柒。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛拨。...
    茶點(diǎn)故事閱讀 38,569評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖举塔,靈堂內(nèi)的尸體忽然破棺而出绑警,到底是詐尸還是另有隱情,我是刑警寧澤央渣,帶...
    沈念sama閱讀 34,254評(píng)論 4 328
  • 正文 年R本政府宣布计盒,位于F島的核電站,受9級(jí)特大地震影響芽丹,放射性物質(zhì)發(fā)生泄漏北启。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,834評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望咕村。 院中可真熱鬧场钉,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,725評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至宇植,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間埋心,已是汗流浹背指郁。 一陣腳步聲響...
    開封第一講書人閱讀 31,950評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留拷呆,地道東北人闲坎。 一個(gè)月前我還...
    沈念sama閱讀 46,260評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像洋腮,于是被迫代替她去往敵國(guó)和親箫柳。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,446評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容