├── LICENSE ├── README.md ├── captcha_example ├── Standard.dat ├── Training.dat ├── main.go └── 验证码图片 │ ├── 0.jpg │ ├── 1.jpg │ ├── 10.jpg │ ├── 100.jpg │ ├── 101.jpg │ ├── 102.jpg │ ├── 103.jpg │ ├── 104.jpg │ ├── 105.jpg │ ├── 106.jpg │ ├── 107.jpg │ ├── 108.jpg │ ├── 109.jpg │ ├── 11.jpg │ ├── 110.jpg │ ├── 111.jpg │ ├── 112.jpg │ ├── 113.jpg │ ├── 114.jpg │ ├── 115.jpg │ ├── 116.jpg │ ├── 117.jpg │ ├── 118.jpg │ ├── 119.jpg │ ├── 12.jpg │ ├── 120.jpg │ ├── 121.jpg │ ├── 122.jpg │ ├── 123.jpg │ ├── 124.jpg │ ├── 125.jpg │ ├── 126.jpg │ ├── 127.jpg │ ├── 128.jpg │ ├── 129.jpg │ ├── 13.jpg │ ├── 130.jpg │ ├── 131.jpg │ ├── 132.jpg │ ├── 133.jpg │ ├── 134.jpg │ ├── 135.jpg │ ├── 136.jpg │ ├── 137.jpg │ ├── 138.jpg │ ├── 139.jpg │ ├── 14.jpg │ ├── 140.jpg │ ├── 141.jpg │ ├── 142.jpg │ ├── 143.jpg │ ├── 144.jpg │ ├── 145.jpg │ ├── 146.jpg │ ├── 147.jpg │ ├── 148.jpg │ ├── 149.jpg │ ├── 15.jpg │ ├── 150.jpg │ ├── 151.jpg │ ├── 152.jpg │ ├── 153.jpg │ ├── 154.jpg │ ├── 155.jpg │ ├── 156.jpg │ ├── 157.jpg │ ├── 158.jpg │ ├── 159.jpg │ ├── 16.jpg │ ├── 160.jpg │ ├── 161.jpg │ ├── 162.jpg │ ├── 163.jpg │ ├── 164.jpg │ ├── 165.jpg │ ├── 166.jpg │ ├── 167.jpg │ ├── 168.jpg │ ├── 169.jpg │ ├── 17.jpg │ ├── 170.jpg │ ├── 171.jpg │ ├── 172.jpg │ ├── 173.jpg │ ├── 174.jpg │ ├── 175.jpg │ ├── 176.jpg │ ├── 177.jpg │ ├── 178.jpg │ ├── 179.jpg │ ├── 18.jpg │ ├── 180.jpg │ ├── 181.jpg │ ├── 182.jpg │ ├── 183.jpg │ ├── 184.jpg │ ├── 185.jpg │ ├── 186.jpg │ ├── 187.jpg │ ├── 188.jpg │ ├── 189.jpg │ ├── 19.jpg │ ├── 190.jpg │ ├── 191.jpg │ ├── 192.jpg │ ├── 193.jpg │ ├── 194.jpg │ ├── 195.jpg │ ├── 196.jpg │ ├── 197.jpg │ ├── 2.jpg │ ├── 20.jpg │ ├── 21.jpg │ ├── 22.jpg │ ├── 23.jpg │ ├── 24.jpg │ ├── 25.jpg │ ├── 26.jpg │ ├── 27.jpg │ ├── 28.jpg │ ├── 29.jpg │ ├── 3.jpg │ ├── 30.jpg │ ├── 31.jpg │ ├── 32.jpg │ ├── 33.jpg │ ├── 34.jpg │ ├── 35.jpg │ ├── 36.jpg │ ├── 37.jpg │ ├── 38.jpg │ ├── 39.jpg │ ├── 4.jpg │ ├── 40.jpg │ ├── 41.jpg │ ├── 42.jpg │ ├── 43.jpg │ ├── 44.jpg │ ├── 45.jpg │ ├── 46.jpg │ ├── 47.jpg │ ├── 48.jpg │ ├── 49.jpg │ ├── 5.jpg │ ├── 50.jpg │ ├── 51.jpg │ ├── 52.jpg │ ├── 53.jpg │ ├── 54.jpg │ ├── 55.jpg │ ├── 56.jpg │ ├── 57.jpg │ ├── 58.jpg │ ├── 59.jpg │ ├── 6.jpg │ ├── 60.jpg │ ├── 61.jpg │ ├── 62.jpg │ ├── 63.jpg │ ├── 64.jpg │ ├── 65.jpg │ ├── 66.jpg │ ├── 67.jpg │ ├── 68.jpg │ ├── 69.jpg │ ├── 7.jpg │ ├── 70.jpg │ ├── 71.jpg │ ├── 72.jpg │ ├── 73.jpg │ ├── 74.jpg │ ├── 75.jpg │ ├── 76.jpg │ ├── 77.jpg │ ├── 78.jpg │ ├── 79.jpg │ ├── 8.jpg │ ├── 80.jpg │ ├── 81.jpg │ ├── 82.jpg │ ├── 83.jpg │ ├── 84.jpg │ ├── 85.jpg │ ├── 86.jpg │ ├── 87.jpg │ ├── 88.jpg │ ├── 89.jpg │ ├── 9.jpg │ ├── 90.jpg │ ├── 91.jpg │ ├── 92.jpg │ ├── 93.jpg │ ├── 94.jpg │ ├── 95.jpg │ ├── 96.jpg │ ├── 97.jpg │ ├── 98.jpg │ └── 99.jpg └── crm2 ├── captcha.go ├── captcha_binaryimage.go ├── captcha_pre.go ├── captcha_test.go └── captcha_util.go /LICENSE: -------------------------------------------------------------------------------- 1 | 2 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 3 | Version 2, December 2004 4 | 5 | Copyright (C) 2004 Sam Hocevar 6 | 7 | Everyone is permitted to copy and distribute verbatim or modified 8 | copies of this license document, and changing it is allowed as long 9 | as the name is changed. 10 | 11 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 12 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 13 | 14 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | capture_easy 2 | ============ 3 | 4 | 一个golang实现简单的验证码识别程序 5 | 6 | -------------------------------------------------------------------------------- /captcha_example/Standard.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/Standard.dat -------------------------------------------------------------------------------- /captcha_example/Training.dat: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/Training.dat -------------------------------------------------------------------------------- /captcha_example/main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "lib/dbgutil" 7 | "log" 8 | "strconv" 9 | ) 10 | 11 | import "crmhelper_private/crm2" 12 | 13 | /* 14 | 1. 下载 100~200 左右验证码,主要是为了囊括 0~9 A~Z a~z 15 | 2. 训练->得到训练模型 16 | 3. 训练模型自动或者手动生成标准模型 17 | 4. 使用标准模型进行识别 18 | */ 19 | 20 | // 通过 21 | const ( 22 | Threshhole = 34000 23 | N = 6 24 | ) 25 | 26 | var trainModuleFile = `d:\CCHelper\Golang\bin\Train.dat` 27 | var stdModuleFile = `d:\CCHelper\Golang\bin\Std.dat` 28 | 29 | func trainloadsave() { 30 | //err:=crm2.ImageColorInfo(in,out string) ==> threshhole = 34000 31 | //err=crm2.DownCaptcha(dir string, n int) ==> get captcha.. 32 | 33 | c := crm2.NewCaptcha(Threshhole, N) 34 | 35 | // 第一次训练 36 | capesOne := make([]image.Image, 0, 97) 37 | // 写入 样本.... 38 | for i := 100; i < 197; i++ { 39 | img, err := crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\` + strconv.Itoa(i) + ".jpg") 40 | if err != nil { 41 | fmt.Println(err) 42 | continue 43 | //log.Fatal(err) 44 | } 45 | capesOne = append(capesOne, img) 46 | } 47 | 48 | trainModule, err := c.Train(capesOne, nil) // nil - newtrainModule 49 | if err != nil { 50 | log.Fatal(err) 51 | } 52 | 53 | for char, binimgs := range trainModule { 54 | fmt.Println(string(char)) 55 | for _, binimg := range binimgs { 56 | fmt.Println(binimg) 57 | } 58 | } 59 | dbgutil.Break() 60 | 61 | err = c.SaveTrainModule(trainModule, trainModuleFile) // 写入文件 62 | if err != nil { 63 | log.Fatal(err) 64 | } 65 | 66 | /* 67 | // 第二次训练 68 | capesTwo := make([]image.Image, 100, 100) 69 | // 写入 样本.... 70 | 71 | trainModule, err = c.Train(capesTwo, trainModuleFile) // nil - newtrainModule 72 | if err != nil { 73 | log.Fatal(err) 74 | } 75 | err = c.SaveTrainModule(trainModule, trainModuleFile) // 写入文件 76 | if err != nil { 77 | log.Fatal(err) 78 | } 79 | */ 80 | 81 | stdModule, err := c.AutoGenStdModuleFromMemory(trainModule) 82 | //or 83 | //stdModule, err := c.AutoGenStdModuleFromFile(trainModuleFile) 84 | if err != nil { 85 | log.Fatal(err) 86 | } 87 | 88 | for char, binimg := range stdModule { 89 | fmt.Println(string(char)) 90 | fmt.Println(binimg) 91 | } 92 | dbgutil.Break() 93 | 94 | err = c.SaveStdModule(stdModule, stdModuleFile) 95 | if err != nil { 96 | log.Fatal(err) 97 | } 98 | 99 | c.ImportStdModule(stdModule) 100 | //or 101 | //stdModule, err := c.LoadStdModule(stdModuleFile) 102 | } 103 | 104 | func recognize() { 105 | c := crm2.NewCaptcha(Threshhole, N) 106 | 107 | //c.ImportStdModule(stdModule) 108 | //or 109 | //_, err := c.LoadStdModule(stdModuleFile) 110 | //stdModule, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Cleaned.dat`) 111 | stdModule, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Std.dat`) 112 | if err != nil { 113 | log.Fatal(err) 114 | } 115 | 116 | for _, char := range c.StdModuleCheck(stdModule, false) { 117 | fmt.Println(string(char)) 118 | } 119 | 120 | for char, binimg := range stdModule { 121 | fmt.Println(string(char)) 122 | fmt.Println(binimg) 123 | } 124 | dbgutil.Break() 125 | 126 | for i := 0; i < 100; i++ { 127 | img, err := crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\` + strconv.Itoa(i) + ".jpg") 128 | if err != nil { 129 | log.Fatal(err) 130 | } 131 | fmt.Println(c.Recognize(img)) 132 | } 133 | } 134 | 135 | func main() { 136 | //trainloadsave() 137 | 138 | //recognize() 139 | 140 | c := crm2.NewCaptcha(Threshhole, N) 141 | train, err := c.LoadTrainModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 142 | if err != nil { 143 | log.Fatal(err) 144 | } 145 | std, err := c.AutoGenStdModuleFromMemory(train) 146 | if err != nil { 147 | log.Fatal(err) 148 | } 149 | fmt.Println("lack : ") 150 | for _, char := range c.StdModuleCheck(std, false) { 151 | fmt.Println(string(char)) 152 | } 153 | 154 | c.ImportStdModule(std) 155 | 156 | for i := 0; i < 100; i++ { 157 | img, err := crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\` + strconv.Itoa(i) + ".jpg") 158 | if err != nil { 159 | log.Fatal(err) 160 | } 161 | fmt.Println(c.Recognize(img)) 162 | } 163 | 164 | } 165 | -------------------------------------------------------------------------------- /captcha_example/验证码图片/0.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/0.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/1.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/1.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/10.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/10.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/100.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/100.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/101.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/101.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/102.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/102.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/103.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/103.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/104.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/104.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/105.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/105.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/106.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/106.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/107.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/107.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/108.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/108.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/109.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/109.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/11.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/11.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/110.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/110.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/111.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/111.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/112.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/112.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/113.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/113.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/114.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/114.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/115.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/115.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/116.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/116.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/117.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/117.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/118.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/118.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/119.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/119.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/12.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/12.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/120.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/120.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/121.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/121.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/122.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/122.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/123.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/123.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/124.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/124.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/125.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/125.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/126.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/126.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/127.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/127.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/128.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/128.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/129.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/129.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/13.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/13.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/130.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/130.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/131.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/131.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/132.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/132.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/133.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/133.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/134.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/134.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/135.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/135.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/136.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/136.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/137.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/137.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/138.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/138.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/139.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/139.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/14.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/14.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/140.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/140.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/141.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/141.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/142.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/142.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/143.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/143.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/144.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/144.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/145.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/145.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/146.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/146.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/147.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/147.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/148.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/148.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/149.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/149.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/15.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/15.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/150.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/150.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/151.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/151.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/152.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/152.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/153.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/153.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/154.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/154.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/155.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/155.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/156.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/156.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/157.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/157.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/158.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/158.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/159.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/159.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/16.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/16.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/160.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/160.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/161.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/161.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/162.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/162.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/163.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/163.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/164.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/164.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/165.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/165.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/166.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/166.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/167.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/167.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/168.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/168.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/169.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/169.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/17.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/17.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/170.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/170.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/171.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/171.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/172.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/172.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/173.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/173.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/174.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/174.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/175.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/175.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/176.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/176.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/177.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/177.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/178.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/178.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/179.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/179.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/18.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/18.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/180.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/180.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/181.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/181.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/182.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/182.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/183.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/183.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/184.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/184.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/185.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/185.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/186.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/186.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/187.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/187.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/188.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/188.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/189.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/189.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/19.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/19.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/190.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/190.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/191.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/191.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/192.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/192.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/193.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/193.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/194.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/194.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/195.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/195.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/196.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/196.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/197.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/197.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/2.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/2.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/20.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/20.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/21.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/21.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/22.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/22.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/23.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/23.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/24.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/24.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/25.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/25.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/26.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/26.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/27.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/27.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/28.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/28.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/29.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/29.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/3.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/3.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/30.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/30.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/31.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/31.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/32.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/33.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/33.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/34.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/34.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/35.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/35.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/36.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/36.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/37.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/37.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/38.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/38.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/39.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/39.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/4.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/4.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/40.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/40.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/41.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/41.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/42.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/42.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/43.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/43.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/44.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/44.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/45.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/45.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/46.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/46.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/47.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/47.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/48.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/48.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/49.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/49.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/5.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/5.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/50.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/50.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/51.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/51.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/52.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/52.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/53.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/53.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/54.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/54.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/55.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/55.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/56.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/56.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/57.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/57.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/58.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/58.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/59.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/59.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/6.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/6.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/60.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/60.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/61.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/61.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/62.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/62.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/63.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/63.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/64.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/64.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/65.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/65.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/66.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/66.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/67.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/67.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/68.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/68.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/69.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/69.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/7.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/7.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/70.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/70.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/71.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/71.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/72.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/72.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/73.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/73.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/74.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/74.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/75.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/75.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/76.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/76.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/77.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/77.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/78.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/78.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/79.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/79.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/8.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/8.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/80.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/80.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/81.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/81.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/82.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/82.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/83.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/83.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/84.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/84.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/85.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/85.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/86.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/86.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/87.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/87.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/88.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/88.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/89.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/89.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/9.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/9.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/90.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/90.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/91.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/91.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/92.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/92.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/93.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/93.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/94.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/94.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/95.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/95.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/96.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/96.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/97.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/97.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/98.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/98.jpg -------------------------------------------------------------------------------- /captcha_example/验证码图片/99.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/goghcrow/capture_easy/ab99de7a316f0487e000e263a5c49b2a20424ac5/captcha_example/验证码图片/99.jpg -------------------------------------------------------------------------------- /crm2/captcha.go: -------------------------------------------------------------------------------- 1 | package crm2 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "image" 7 | "io/ioutil" 8 | "log" 9 | "os" 10 | "strconv" 11 | ) 12 | 13 | type Alpha byte 14 | 15 | // 仅支持大小写字母与数字 16 | type Captcha struct { 17 | N int //验证码图片字符数量 18 | Threshold int // 阈值 34000 19 | StdModule map[Alpha]BinaryImage 20 | } 21 | 22 | // constructor 23 | func NewCaptcha( /*image image.Image,*/ threshold, n int) *Captcha { 24 | return &Captcha{ 25 | N: n, 26 | //Image: image, 27 | Threshold: threshold, 28 | } 29 | } 30 | 31 | // 通用二值化 32 | func (c *Captcha) Binarify(img image.Image) BinaryImage { 33 | // 去除1px边缘 34 | h := img.Bounds().Dy() - 2 35 | w := img.Bounds().Dx() - 2 36 | 37 | //int Img[h][w] 38 | binimg := make([][]int, h) 39 | for i, l := 0, h; i < l; i++ { 40 | binimg[i] = make([]int, w) 41 | } 42 | 43 | for y := 1; y < h+1; y++ { 44 | for x := 1; x < w+1; x++ { 45 | // ps里头查看验证码,发现蓝通道对比较大 46 | // 直接通过蓝通道二值化处理 47 | _, _, b, _ := img.At(x, y).RGBA() 48 | if b < uint32(c.Threshold) { 49 | binimg[y-1][x-1] = 1 50 | } else { 51 | binimg[y-1][x-1] = 0 52 | } 53 | } 54 | } 55 | return BinaryImage(binimg) 56 | } 57 | 58 | // !panic 二值化并 切割并复制子区域 59 | func (c *Captcha) Crop(img image.Image) []BinaryImage { 60 | return c.Binarify(img).CropSubImgNoPanic(c.N) 61 | } 62 | 63 | // 从文件读取并解码模板 64 | func (c *Captcha) decodeModuleFile(moduleFile string, to interface{}) error { 65 | f, err := os.Open(moduleFile) 66 | if err != nil { 67 | return err 68 | } 69 | defer f.Close() 70 | en, err := ioutil.ReadAll(f) 71 | if err != nil { 72 | return err 73 | } 74 | err = ByteDecode(en, to) 75 | if err != nil { 76 | return err 77 | } 78 | return nil 79 | } 80 | 81 | // 将模板写入文件 文件存在则覆盖 82 | func (c *Captcha) encodeModuleFile(module interface{}, moduleFile string) error { 83 | f, err := os.Create(moduleFile) 84 | if err != nil { 85 | return err 86 | } 87 | defer f.Close() 88 | 89 | en, err := ByteEncode(module) 90 | if err != nil { 91 | return err 92 | } 93 | 94 | _, err = f.Write(en) 95 | if err != nil { 96 | return err 97 | } 98 | return nil 99 | } 100 | 101 | // 载入标准模板文件 (notice:自动调用ImportStdModule,覆盖就stdMobule) 102 | func (c *Captcha) LoadStdModule(stdfile string) (map[Alpha]BinaryImage, error) { 103 | stdModule := make(map[Alpha]BinaryImage) 104 | err := c.decodeModuleFile(stdfile, &stdModule) 105 | if err != nil { 106 | return nil, err 107 | } 108 | c.ImportStdModule(stdModule) 109 | return stdModule, nil 110 | } 111 | 112 | // 更新标准模板某个字符 Load -> update 未写入文件 -> Save 113 | func (c *Captcha) UpdateStdModule(a Alpha, binimg BinaryImage) { 114 | if c.StdModule == nil { 115 | panic("must improtStdModule first") 116 | } 117 | c.StdModule[a] = binimg 118 | } 119 | 120 | // 保存标准模板文件 121 | func (c *Captcha) SaveStdModule(stdModule map[Alpha]BinaryImage, stdfile string) error { 122 | return c.encodeModuleFile(stdModule, stdfile) 123 | } 124 | 125 | // 载入训练文件 126 | func (c *Captcha) LoadTrainModule(trainFile string) (map[Alpha][]BinaryImage, error) { 127 | trainModule := make(map[Alpha][]BinaryImage) 128 | err := c.decodeModuleFile(trainFile, &trainModule) 129 | if err != nil { 130 | return nil, err 131 | } 132 | return trainModule, nil 133 | } 134 | 135 | // 保存训练文件 136 | func (c *Captcha) SaveTrainModule(trainModule map[Alpha][]BinaryImage, trainFile string) error { 137 | return c.encodeModuleFile(trainModule, trainFile) 138 | } 139 | 140 | // 手动从训练模板生成标准模板 未写入文件 需手动调用 SaveStdModule 141 | func (c *Captcha) ManualGenStdModuleFromFile(trainFileFrom string) (map[Alpha]BinaryImage, error) { 142 | trainModule, err := c.LoadTrainModule(trainFileFrom) 143 | if err != nil { 144 | return nil, err 145 | } 146 | stdModule := make(map[Alpha]BinaryImage) 147 | 148 | for alpha, binimges := range trainModule { 149 | stdModule[alpha] = binimges[c.manualFindMatchest(alpha, binimges)] 150 | } 151 | return stdModule, nil 152 | } 153 | 154 | // 手动寻找最匹配 155 | func (c *Captcha) manualFindMatchest(alpha Alpha, binimges []BinaryImage) int { 156 | for i, l := 0, len(binimges); i < l; i++ { 157 | fmt.Printf("==================== Index :[ %d ] ==============\n", i) 158 | fmt.Printf("==================== Alpha :[ %s ] ==============\n", string(byte(alpha))) 159 | fmt.Println(binimges[i]) 160 | } 161 | 162 | r := bufio.NewReader(os.Stdin) 163 | line, err := r.ReadSlice('\n') 164 | if err != nil { 165 | log.Fatal(err) 166 | } 167 | 168 | index, err := strconv.Atoi(string(line[0])) 169 | if err != nil { 170 | log.Fatal(err) 171 | } 172 | return index 173 | } 174 | 175 | // 自动从训练模板生成标准模板 未写入文件 需手动调用 SaveStdModule 176 | func (c *Captcha) AutoGenStdModuleFromFile(trainFileFrom string) (map[Alpha]BinaryImage, error) { 177 | trainModule, err := c.LoadTrainModule(trainFileFrom) 178 | if err != nil { 179 | return nil, err 180 | } 181 | return c.AutoGenStdModuleFromMemory(trainModule) 182 | } 183 | 184 | // 自动从训练模板生成标准模板 未写入文件 需手动调用 SaveStdModule 185 | func (c *Captcha) AutoGenStdModuleFromMemory(trainModule map[Alpha][]BinaryImage) (map[Alpha]BinaryImage, error) { 186 | stdModule := make(map[Alpha]BinaryImage) 187 | 188 | for alpha, binimges := range trainModule { 189 | stdModule[alpha] = binimges[c.autoFindMatchest(binimges)] 190 | } 191 | return stdModule, nil 192 | } 193 | 194 | // 自动寻找最匹配 195 | func (c *Captcha) autoFindMatchest(binimges []BinaryImage) int { 196 | // 规则,比较[]BinImg指纹位数 197 | // 以占数量最多的位数为准 198 | // 在同样位数的[]BinImg寻找每一位出现0与1的数量,以次数多的为准 199 | // 最终生成平均的指纹...覆盖大部分情况... 200 | 201 | bl := len(binimges) 202 | 203 | ///////////////////////// 204 | // 生成标准化指纹,取数量最多者 205 | // 指纹序列组 206 | fpseq := make([][]byte, bl, bl) 207 | // 指纹序列长度频数序列 208 | lenseq := make(map[int]int) // 这里如果使用俩slice代替map,生成norLseq就可以生一次遍历len() 209 | for i := 0; i < bl; i++ { 210 | h, w := len(binimges[i]), len(binimges[i][0]) // !panic empty bi 211 | fpseq[i] = binimges[i].FingerPrint(h, w) 212 | tl := len(fpseq[i]) 213 | if _, ok := lenseq[tl]; ok { 214 | lenseq[tl]++ 215 | } else { 216 | lenseq[tl] = 1 217 | } 218 | } 219 | 220 | // 去频数序列中最大值 221 | norL := 0 // 指纹标准长度值 222 | maxC := 0 // 指纹标准长度值在序列中个数 223 | for l, c := range lenseq { 224 | if c > maxC { 225 | maxC = c 226 | norL = l 227 | } 228 | } 229 | 230 | // 从指纹序列组中去除小于长度频数的指纹序列 231 | norFpseq := make([][]byte, 0, maxC) // 标准化之后的指纹序列组 232 | //norFpseq := make([][]byte, maxC, maxC) // 标准化之后的指纹序列组 233 | // init 234 | //for i := 0; i < maxC; i++ { 235 | // norFpseq[i] = make([]byte, norL, norL) 236 | //} 237 | //currI := 0 238 | for i := 0; i < bl; i++ { 239 | if len(fpseq[i]) == norL { 240 | norFpseq = append(norFpseq, fpseq[i]) 241 | //norFpseq[currI] = fpseq[i] 242 | //currI++ 243 | } 244 | } 245 | 246 | // 标准指纹序列 247 | norFp := make([]byte, norL, norL) 248 | for i := 0; i < norL; i++ { // 序列中第几位 249 | oneC := 0 250 | zeroC := 0 251 | for j := 0; j < maxC; j++ { // j 序列组中第几个序列 252 | if norFpseq[j][i] == 1 { 253 | oneC++ 254 | } else { 255 | zeroC++ 256 | } 257 | } 258 | // 宁多勿少 259 | if oneC >= zeroC { 260 | norFp[i] = 0 261 | } else { 262 | norFp[i] = 1 263 | } 264 | } 265 | //////////////////////////// 266 | 267 | // 取[]BinaryImage与标准化指纹最similar值最小的index 268 | minN := 100 269 | minIndex := 0 270 | for i := 0; i < bl; i++ { 271 | if len(fpseq[i]) == norL { 272 | if n := Hamming(fpseq[i], norFp); n < minN { 273 | minN = n 274 | minIndex = i 275 | } 276 | } 277 | } 278 | return minIndex 279 | } 280 | 281 | // 从已有文件导入训练或者重新(trainFile = nil)训练模板,返回训练模板 未写入文件 需手动调用 SaveTrainModule 282 | func (c *Captcha) Train(capimgs []image.Image, trainFile interface{}) (map[Alpha][]BinaryImage, error) { 283 | trainModule := make(map[Alpha][]BinaryImage) 284 | if trainFile != nil { 285 | var err error 286 | trainModule, err = c.LoadTrainModule(trainFile.(string)) 287 | if err != nil { 288 | return nil, err 289 | } 290 | } 291 | 292 | r := bufio.NewReader(os.Stdin) 293 | for i, l := 0, len(capimgs); i < l; i++ { 294 | 295 | capbinimg := c.Binarify(capimgs[i]) 296 | 297 | fmt.Println(capbinimg) 298 | fmt.Println("enter captcha: ") 299 | 300 | input: 301 | captch, err := r.ReadSlice('\n') 302 | //fmt.Println(len(captch)) // 8 = 6+ \n \ r 303 | if len(captch) != (c.N + 2) { 304 | fmt.Println("len(captch) != c.N") 305 | goto input 306 | } 307 | if err != nil { 308 | fmt.Println(err) 309 | goto input 310 | } 311 | binimges := capbinimg.CropSubImgNoPanic(c.N) 312 | 313 | if binimges == nil { 314 | fmt.Println("crop failed,next") 315 | continue 316 | } 317 | // 将输入的验证码与crop关联存入训练module 318 | for n := 0; n < c.N; n++ { 319 | alpha := Alpha(captch[n]) 320 | if _, ok := trainModule[alpha]; ok { 321 | trainModule[alpha] = append(trainModule[alpha], binimges[n]) 322 | } else { 323 | trainModule[alpha] = []BinaryImage{binimges[n]} 324 | } 325 | } 326 | 327 | } 328 | return trainModule, nil 329 | } 330 | 331 | // 标准模板检查 测试训练后缺少哪些字符 332 | func (c *Captcha) StdModuleCheck(stdModule map[Alpha]BinaryImage, show bool) []byte { 333 | lacks := make([]byte, 0, 62) 334 | 335 | var char byte 336 | if show { 337 | fmt.Println("lack : ") 338 | fmt.Print(" num : ") 339 | } 340 | for char = '0'; char <= '9'; char++ { 341 | if _, ok := stdModule[Alpha(char)]; !ok { 342 | if show { 343 | fmt.Printf("(last %s)current [%s] ", string(char-1), string(char)) 344 | } 345 | lacks = append(lacks, char) 346 | } 347 | } 348 | if show { 349 | fmt.Print("\n upper : ") 350 | } 351 | for char = 'A'; char <= 'Z'; char++ { 352 | if _, ok := stdModule[Alpha(char)]; !ok { 353 | if show { 354 | fmt.Printf("(last %s)current [%s] ", string(char-1), string(char)) 355 | } 356 | lacks = append(lacks, char) 357 | } 358 | } 359 | if show { 360 | fmt.Println("\n lower : ") 361 | } 362 | for char = 'a'; char <= 'z'; char++ { 363 | if _, ok := stdModule[Alpha(char)]; !ok { 364 | if show { 365 | fmt.Printf("(last %s)current [%s] ", string(char-1), string(char)) 366 | } 367 | lacks = append(lacks, char) 368 | } 369 | } 370 | if show { 371 | fmt.Println() 372 | } 373 | return lacks 374 | } 375 | 376 | // 导入标准模板,再次导入执行覆盖 377 | func (c *Captcha) ImportStdModule(stdModule map[Alpha]BinaryImage) { 378 | if c.StdModule == nil { 379 | c.StdModule = make(map[Alpha]BinaryImage) 380 | } 381 | c.StdModule = stdModule 382 | } 383 | 384 | // 识别前必须先导入标准模板 385 | func (c *Captcha) Recognize(img image.Image) string { 386 | if c.StdModule == nil { 387 | panic("must improtStdModule first") 388 | } 389 | 390 | cropsBinimgs := c.Binarify(img).CropSubImg(c.N) 391 | 392 | var recognized = make([]byte, c.N, c.N) 393 | 394 | for i := 0; i < c.N; i++ { 395 | 396 | var ( 397 | min int = 100 // 汉明距离 398 | A Alpha 399 | ) 400 | 401 | for alpha, stdbinimg := range c.StdModule { 402 | hamming := stdbinimg.Similarity(cropsBinimgs[i]) 403 | if hamming < min { 404 | min = hamming 405 | A = alpha 406 | } 407 | } 408 | 409 | recognized[i] = byte(A) 410 | } 411 | return string(recognized) 412 | } 413 | -------------------------------------------------------------------------------- /crm2/captcha_binaryimage.go: -------------------------------------------------------------------------------- 1 | package crm2 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "image" 7 | "strconv" 8 | ) 9 | 10 | // 脚的 定义成内嵌 [][]int 的struct更方便,懒得改了 11 | type BinaryImage [][]int 12 | 13 | // !panic 14 | func (bi BinaryImage) String() string { 15 | binimg := [][]int(bi) 16 | h := len(binimg) 17 | if h < 1 { 18 | panic("len(binimg) < 1") 19 | } 20 | w := len(binimg[0]) 21 | if w < 1 { 22 | panic("len(binimg[0] < 1") 23 | } 24 | return bi.RectString(image.Rect(0, 0, w-1, h-1)) 25 | } 26 | 27 | func (bi BinaryImage) RectString(rect image.Rectangle) string { 28 | binimg := [][]int(bi) 29 | buf := bytes.NewBuffer(nil) 30 | for y, maxy := rect.Min.Y, rect.Max.Y; y <= maxy; y++ { 31 | for x, maxx := rect.Min.X, rect.Max.X; x <= maxx; x++ { 32 | /*_, err := */ buf.WriteString(strconv.Itoa(binimg[y][x])) 33 | } 34 | buf.WriteByte('\n') 35 | } 36 | return buf.String() 37 | } 38 | 39 | // 返回sub BinaryImage 40 | func (bi BinaryImage) SubBinaryImage(rect image.Rectangle) BinaryImage { 41 | binimg := BinaryImage(bi) 42 | h, w := rect.Size().Y+1, rect.Size().X+1 43 | 44 | // init 45 | newbi := make([][]int, h, h) 46 | for y := 0; y < h; y++ { 47 | newbi[y] = make([]int, w, w) 48 | } 49 | 50 | // copy 51 | for y := 0; y < h; y++ { 52 | copy(newbi[y], binimg[rect.Min.Y+y][rect.Min.X:rect.Max.X+1]) 53 | } 54 | return BinaryImage(newbi) 55 | } 56 | 57 | // !panic 数组越界 返回切割成n块的区域 58 | func (bi BinaryImage) CropRect(n int) []image.Rectangle { 59 | rectes := make([]image.Rectangle, n, n) 60 | binimg := [][]int(bi) 61 | maxY := len(binimg) 62 | if maxY == 0 { 63 | panic("empty binaryimage : h == 0") 64 | } 65 | maxX := len(binimg[0]) 66 | if maxX == 0 { 67 | panic("empty binaryimage : w == 0") 68 | } 69 | 70 | XS := make([]bool, maxX, maxX) 71 | for x := 0; x < maxX; x++ { 72 | for y := 0; y < maxY; y++ { 73 | if binimg[y][x] == 1 { 74 | XS[x] = true 75 | break 76 | } 77 | } 78 | } 79 | 80 | minXs := make([]int, 0, 6) 81 | maxXs := make([]int, 0, 6) 82 | // 验证码可能在最后竖列,(暂时未发现可能在第一竖列) 83 | // bug 必须连续两竖排才OK --> 小写I 不对 84 | // bug 不能处理不连续的... 85 | for x := 1; x < maxX-1; x++ { 86 | switch { 87 | //case : // 不连续,暂时不考虑边缘数组越界 88 | // 89 | //case : // 不连续,暂时不考虑边缘数组越界 90 | // 91 | 92 | case !XS[x-1] && XS[x] && XS[x+1]: // 连续 93 | minXs = append(minXs, x-1) 94 | case XS[x-1] && XS[x] && !XS[x+1]: // 连续 95 | maxXs = append(maxXs, x+1) 96 | case !XS[x-1] && XS[x] && !XS[x+1]: // 小写I 97 | count := 0 98 | for y := 0; y < maxY; y++ { 99 | // 中间像素>10,两旁无像素 100 | if binimg[y][x-1] == 1 || binimg[y][x+1] == 1 { 101 | goto end 102 | } 103 | if binimg[y][x] == 1 { // black 104 | count++ 105 | } 106 | } 107 | if count >= 10 { 108 | minXs = append(minXs, x-1) 109 | maxXs = append(maxXs, x+1) 110 | } 111 | end: 112 | } 113 | } 114 | 115 | // 最后一竖列 116 | // todo 最后也必须验证三个 117 | if len(maxXs) == 5 && XS[maxX-2] && XS[maxX-1] { 118 | maxXs = append(maxXs, maxX-1) 119 | } 120 | 121 | if len(maxXs) != 6 || len(minXs) != 6 { 122 | panic(fmt.Sprintf("len(maxXs) = %d || len(minXs) = %d", len(maxXs), len(minXs))) 123 | } 124 | 125 | for i := 0; i < 6; i++ { 126 | rectes[i] = image.Rectangle{image.Point{minXs[i], 0}, image.Point{maxXs[i], 0}} 127 | } 128 | 129 | // 针对每个x区域扫描y 130 | YS := make([]bool, maxY, maxY) 131 | for i := 0; i < 6; i++ { 132 | 133 | for y := 0; y < maxY; y++ { 134 | for x := rectes[i].Min.X; x < rectes[i].Max.X; x++ { 135 | if binimg[y][x] == 1 { 136 | YS[y] = true 137 | break 138 | } 139 | } 140 | } 141 | 142 | // bug : 未考虑最后一个 143 | // 验证码可能在第一横行和最后一横行,所以必须考虑特殊情况 144 | // 扩展1像素 ?? 145 | // 验证三个 小写I 不对 146 | 147 | for y, l := 1, maxY>>1; y < l; y++ { 148 | if !YS[y-1] && YS[y] && YS[y+1] { // 连续 149 | rectes[i].Min.Y = y - 1 150 | break 151 | } 152 | } 153 | for y, l := maxY-2, maxY>>1; y > l; y-- { 154 | if YS[y-1] && YS[y] && !YS[y+1] { // 连续 155 | rectes[i].Max.Y = y + 1 156 | break 157 | } 158 | } 159 | // 边缘 160 | if YS[maxY-2] && YS[maxY-1] { 161 | rectes[i].Max.Y = maxY - 1 162 | } 163 | 164 | // YS Reset 165 | for j := 0; j < maxY; j++ { 166 | YS[j] = false 167 | } 168 | } 169 | return rectes 170 | } 171 | 172 | // !panic 返回n块复制的切割区域 173 | func (bi BinaryImage) CropSubImg(n int) []BinaryImage { 174 | rectes := bi.CropRect(n) 175 | subbis := make([]BinaryImage, n, n) 176 | for i := 0; i < n; i++ { 177 | subbis[i] = bi.SubBinaryImage(rectes[i]) 178 | } 179 | return subbis 180 | } 181 | 182 | func (bi BinaryImage) CropSubImgNoPanic(n int) (subbis []BinaryImage) { 183 | subbis = make([]BinaryImage, n, n) 184 | defer func() { 185 | if recover() != nil { 186 | subbis = nil 187 | } 188 | }() 189 | return bi.CropSubImg(n) 190 | } 191 | 192 | // !panic(未检测BinaryImage是否为空) 计算相似度 <= 5 相似 大于 10 不同 193 | func (bi BinaryImage) Similarity(anobi BinaryImage) int { 194 | a, b := [][]int(bi), [][]int(anobi) 195 | var h, w int 196 | if ha, hb := len(a), len(b); ha < hb { 197 | h = ha 198 | } else { 199 | h = hb 200 | } 201 | if wa, wb := len(a[0]), len(b[0]); wa < wb { 202 | w = wa 203 | } else { 204 | w = wb 205 | } 206 | pfa := bi.FingerPrint(h, w) 207 | pfb := anobi.FingerPrint(h, w) 208 | 209 | return Hamming(pfa, pfb) 210 | } 211 | 212 | // !panic(未检测BinaryImage是否为空) 计算指纹 213 | func (bi BinaryImage) FingerPrint(h, w int) []byte { 214 | binimg := [][]int(bi) 215 | var ( 216 | sum float32 217 | avg float32 218 | ) 219 | for y := 0; y < h; y++ { 220 | for x := 0; x < w; x++ { 221 | sum += float32(binimg[y][x]) 222 | } 223 | } 224 | 225 | avg = sum / (float32(h) * float32(w)) 226 | 227 | buf := bytes.NewBuffer(nil) 228 | 229 | for y := 0; y < h; y++ { 230 | for x := 0; x < w; x++ { 231 | if float32(binimg[y][x]) >= avg { 232 | buf.WriteByte('1') 233 | } else { 234 | buf.WriteByte('0') 235 | } 236 | } 237 | } 238 | return buf.Bytes() 239 | } 240 | -------------------------------------------------------------------------------- /crm2/captcha_pre.go: -------------------------------------------------------------------------------- 1 | // captcha 预处理 2 | package crm2 3 | 4 | import ( 5 | "fmt" 6 | "image" 7 | "image/color" 8 | "image/jpeg" 9 | "io" 10 | "os" 11 | "strconv" 12 | ) 13 | 14 | const CAPURL = `http://om.jd.com/auth_authImg` 15 | 16 | var ( 17 | white = color.RGBA{255, 255, 255, 255} 18 | black = color.RGBA{0, 0, 0, 255} 19 | ) 20 | 21 | // 下载n个验证码到文件夹 22 | func DownCaptcha(dir string, n int) error { 23 | crm := New(TEST_ERP, TEST_PWD, n, 23000) 24 | err := crm.SetProxy(TEST_PROXY) 25 | if err != nil { 26 | return err 27 | } 28 | err = crm.Login() 29 | if err != nil { 30 | return err 31 | } 32 | 33 | ch := make(chan int, n) 34 | for i := 0; i < n; i++ { 35 | ch <- i 36 | } 37 | 38 | MultiTaskDone(n, func() { 39 | f, err := os.Create(dir + strconv.Itoa(<-ch) + ".jpg") 40 | if err != nil { 41 | fmt.Println("create file error : ", err) 42 | return 43 | } 44 | defer f.Close() 45 | resp, err := crm.HttpClient.Get(CAPURL) 46 | if err != nil { 47 | fmt.Println("http get error : ", err) 48 | return 49 | } 50 | defer resp.Body.Close() 51 | 52 | io.Copy(f, resp.Body) 53 | }) 54 | return nil 55 | } 56 | 57 | // 验证码去则色输出 阈值..34000 58 | func ImageClean(in, out string, threshole int) error { 59 | f, err := os.Open(in) 60 | if err != nil { 61 | return err 62 | } 63 | defer f.Close() 64 | o, err := os.Create(out) 65 | if err != nil { 66 | return err 67 | } 68 | defer o.Close() 69 | 70 | m, _, err := image.Decode(f) 71 | if err != nil { 72 | return err 73 | } 74 | 75 | bounds := m.Bounds() 76 | white := color.RGBA{255, 255, 255, 255} 77 | black := color.RGBA{0, 0, 0, 255} 78 | // 去除边缘 79 | minX, maxX, minY, maxY := bounds.Min.X+1, bounds.Max.X-1, bounds.Min.Y+1, bounds.Max.Y-1 80 | img := image.NewNRGBA(image.Rect(0, 0, maxX-1, maxY-1)) 81 | for y := minY; y < maxY; y++ { 82 | for x := minX; x < maxX; x++ { 83 | _, _, b, _ := m.At(x, y).RGBA() 84 | if b < uint32(threshole) { 85 | img.Set(x-1, y-1, black) 86 | } else { 87 | img.Set(x-1, y-1, white) 88 | } 89 | } 90 | } 91 | 92 | opt := &jpeg.Options{Quality: 100} 93 | err = jpeg.Encode(o, img, opt) 94 | if err != nil { 95 | return err 96 | } 97 | return nil 98 | } 99 | 100 | // 统计图像色彩信息,可以用excel做直方图,根据色彩范围确定验证码的阈值 101 | func ImageColorInfo(in, out string) error { 102 | f, err := os.Open(in) 103 | if err != nil { 104 | return err 105 | } 106 | defer f.Close() 107 | 108 | m, _, err := image.Decode(f) 109 | if err != nil { 110 | return err 111 | } 112 | bounds := m.Bounds() 113 | // 去除边缘 114 | minX, maxX, minY, maxY := bounds.Min.X+1, bounds.Max.X-1, bounds.Min.Y+1, bounds.Max.Y-1 115 | 116 | s := make(map[uint32]uint32) 117 | for y := minY; y < maxY; y++ { 118 | for x := minX + 1; x < maxX; x++ { 119 | //r, g, b, _ := m.At(x, y).RGBA() 120 | _, _, b, _ := m.At(x, y).RGBA() 121 | if _, ok := s[b]; ok { 122 | s[b] += 1 123 | } else { 124 | s[b] = 1 125 | } 126 | } 127 | } 128 | 129 | o, err := os.Create(out) 130 | if err != nil { 131 | return err 132 | } 133 | defer o.Close() 134 | for k, v := range s { 135 | fmt.Fprintf(o, "%d,%d\n", k, v) 136 | } 137 | return nil 138 | } 139 | -------------------------------------------------------------------------------- /crm2/captcha_test.go: -------------------------------------------------------------------------------- 1 | package crm2 2 | 3 | import ( 4 | "fmt" 5 | "image" 6 | "lib/dbgutil" 7 | "log" 8 | "testing" 9 | ) 10 | 11 | const ( 12 | Threshole = 34000 13 | N = 6 14 | ) 15 | 16 | var c *Captcha 17 | var img image.Image 18 | 19 | func init() { 20 | var err error 21 | img, err = ReadImg(`d:\CCHelper\Golang\bin\验证码\0.jpg`) 22 | if err != nil { 23 | log.Fatal(err) 24 | } 25 | c = NewCaptcha(Threshole, N) 26 | } 27 | 28 | // 只简单测试了函数的功能,嵌套函数只测试最外层函数 29 | // 加下划线(暂时注释):通过测试...每个函数单独测试 30 | 31 | /// test binaryimage Region 32 | 33 | // OK 34 | func TestBiString(t *testing.T) { 35 | t.Log(c.Binarify(img)) 36 | crops := c.Crop(img) 37 | for i, l := 0, len(crops); i < l; i++ { 38 | t.Log(crops[i]) 39 | } 40 | } 41 | 42 | // OK 43 | func TestSimilarity(t *testing.T) { 44 | crops := c.Crop(img) 45 | sameN := crops[0].Similarity(crops[0]) 46 | diffN := crops[0].Similarity(crops[1]) 47 | t.Log(sameN) 48 | t.Log(diffN) 49 | if sameN != 0 { 50 | t.Fail() 51 | } 52 | if diffN <= 5 { 53 | t.Fail() 54 | } 55 | 56 | } 57 | 58 | /// test capture Region 59 | 60 | // OK 61 | func TestBinarify(t *testing.T) { 62 | dbgutil.FormatDisplay("Binaryfy", c.Binarify(img)) 63 | } 64 | 65 | // OK 66 | func TestCrop(t *testing.T) { 67 | dbgutil.FormatDisplay("Crop", c.Crop(img)) 68 | } 69 | 70 | // OK 71 | func TestLoadModule(t *testing.T) { 72 | train, err := c.LoadTrainModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 73 | if err != nil { 74 | t.Fatal(err) 75 | } 76 | dbgutil.FormatDisplay("train", train) 77 | 78 | std, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Cleaned.dat`) 79 | if err != nil { 80 | t.Fatal(err) 81 | } 82 | dbgutil.FormatDisplay("std", std) 83 | } 84 | 85 | // OK 86 | func TestAutoGenStdModule(t *testing.T) { 87 | //trainModule, err := c.LoadTrainModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 88 | //if err != nil { 89 | // t.Fatal(err) 90 | //} 91 | //for _, zero := range trainModule['0'] { 92 | // fmt.Println(zero) 93 | //} 94 | //t.Log(c.autoFindMatchest(trainModule['0'])) 95 | stdModule, err := c.AutoGenStdModuleFromFile(`d:\CCHelper\Golang\bin\Alphabet.dat`) 96 | if err != nil { 97 | t.Fatal(err) 98 | } 99 | for alpha, binimg := range stdModule { 100 | t.Logf("==[ %s ]==\n%s", string(alpha), binimg.String()) 101 | } 102 | } 103 | 104 | /* 105 | func TestManualGenStdModule(t *testing.T) { 106 | stdModule, err := c.ManualGenStdModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 107 | if err != nil { 108 | t.Fatal(err) 109 | } 110 | for alpha, binimg := range stdModule { 111 | t.Logf("==[ %s ]==\n%s", string(alpha), binimg.String()) 112 | } 113 | } 114 | 无法使用测试框架测试此函数,单独测试 115 | package main 116 | 117 | import ( 118 | "crmhelper_private/crm2" 119 | "fmt" 120 | "log" 121 | ) 122 | 123 | const Threshole = 34000 124 | const N = 6 125 | var c *crm2.Captcha 126 | 127 | func init() { 128 | img, err := crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\0.jpg`) 129 | if err != nil { 130 | log.Fatal(err) 131 | } 132 | c = crm2.NewCaptcha(img, Threshole, N) 133 | } 134 | 135 | func main() { 136 | stdModule, err := c.ManualGenStdModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 137 | if err != nil { 138 | log.Fatal(err) 139 | } 140 | for alpha, binimg := range stdModule { 141 | fmt.Printf("==[ %s ]==\n%s", string(alpha), binimg.String()) 142 | } 143 | } 144 | */ 145 | 146 | func TestSaveTrainModule(t *testing.T) { 147 | train, err := c.LoadTrainModule(`d:\CCHelper\Golang\bin\Alphabet.dat`) 148 | if err != nil { 149 | t.Fatal(err) 150 | } 151 | err = c.SaveTrainModule(train, `d:\CCHelper\Golang\bin\Alphabet_Test.dat`) 152 | if err != nil { 153 | t.Fatal(err) 154 | } 155 | } 156 | 157 | func TestSaveStdModule(t *testing.T) { 158 | train, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Cleaned.dat`) 159 | if err != nil { 160 | t.Fatal(err) 161 | } 162 | err = c.SaveStdModule(train, `d:\CCHelper\Golang\bin\Cleaned_Test.dat`) 163 | if err != nil { 164 | t.Fatal(err) 165 | } 166 | } 167 | 168 | /* 169 | func TestTrain(t *testing.T) { 170 | 171 | } 172 | 无法测试,新文件测试 173 | func main() { 174 | imgs := make([]image.Image, 5, 5) 175 | imgs[0], _ = crm2.ReadImg(`d:\CCHelper\Golang\bin\@jjjjj.jpg`) 176 | imgs[1], _ = crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\32.jpg`) 177 | imgs[2], _ = crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\12.jpg`) 178 | imgs[3], _ = crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\7.jpg`) 179 | imgs[4], _ = crm2.ReadImg(`d:\CCHelper\Golang\bin\验证码\55.jpg`) 180 | tm, err := c.Train(imgs, nil) 181 | if err != nil { 182 | log.Fatal(err) 183 | } 184 | dbgutil.FormatDisplay("", tm) 185 | } 186 | */ 187 | 188 | func TestRecognize(t *testing.T) { 189 | _, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Cleaned.dat`) 190 | if err != nil { 191 | log.Fatal(err) 192 | } 193 | 194 | img, err := ReadImg(`d:\CCHelper\Golang\bin\@IIIIIIIIIII.jpg`) 195 | if err != nil { 196 | log.Fatal(err) 197 | } 198 | recognized := c.Recognize(img) 199 | t.Log(recognized) 200 | } 201 | 202 | func TestStdModuleCheck(t *testing.T) { 203 | std, err := c.LoadStdModule(`d:\CCHelper\Golang\bin\Cleaned.dat`) 204 | if err != nil { 205 | log.Fatal(err) 206 | } 207 | fmt.Println(c.StdModuleCheck(std, false)) 208 | 209 | fmt.Println(c.StdModuleCheck(make(map[Alpha]BinaryImage), true)) 210 | } 211 | -------------------------------------------------------------------------------- /crm2/captcha_util.go: -------------------------------------------------------------------------------- 1 | // todo 加入压缩与解压,加入读取与写入文件两个包装函数 2 | package crm2 3 | 4 | import ( 5 | "bytes" 6 | "encoding/gob" 7 | "fmt" 8 | "image" 9 | "image/jpeg" 10 | "os" 11 | ) 12 | 13 | // !panic 计算字节数组汉明距离 n <= 5 true n > 10 false 14 | func Hamming(a, b []byte) (n int) { 15 | l := len(a) 16 | if l != len(b) { 17 | panic(fmt.Errorf("Hamming len(a)[%d] != len(b)[%d]", l, len(b))) 18 | } 19 | for i := 0; i < l; i++ { 20 | if a[i] != b[i] { 21 | n += 1 22 | } 23 | } 24 | return 25 | } 26 | 27 | // 从文件读取imgage 28 | func ReadImg(imgFile string) (image.Image, error) { 29 | f, err := os.Open(imgFile) 30 | if err != nil { 31 | return nil, err 32 | } 33 | img, err := jpeg.Decode(f) 34 | if err != nil { 35 | return nil, err 36 | } 37 | return img, nil 38 | } 39 | 40 | // @from http://golanghome.com/post/346 41 | func ByteEncode(data interface{}) ([]byte, error) { 42 | buf := bytes.NewBuffer(nil) 43 | enc := gob.NewEncoder(buf) 44 | err := enc.Encode(data) 45 | if err != nil { 46 | return nil, err 47 | } 48 | return buf.Bytes(), nil 49 | } 50 | 51 | // @from http://golanghome.com/post/346 52 | // to 必须为point 53 | func ByteDecode(data []byte, to interface{}) error { 54 | buf := bytes.NewBuffer(data) 55 | dec := gob.NewDecoder(buf) 56 | return dec.Decode(to) 57 | } 58 | --------------------------------------------------------------------------------