附近小店
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

ocr.go 12 KiB

3 months ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386
  1. package weapp
  2. const (
  3. apiBankcard = "/cv/ocr/bankcard"
  4. apiVehicleLicense = "/cv/ocr/driving"
  5. apiDrivingLicense = "/cv/ocr/drivinglicense"
  6. apiIDCard = "/cv/ocr/idcard"
  7. apiBusinessLicense = "/cv/ocr/bizlicense"
  8. apiPrintedText = "/cv/ocr/comm"
  9. )
  10. // RecognizeMode 图片识别模式
  11. type RecognizeMode = string
  12. // 所有图片识别模式
  13. const (
  14. RecognizeModePhoto RecognizeMode = "photo" // 拍照模式
  15. RecognizeModeScan RecognizeMode = "scan" // 扫描模式
  16. )
  17. // BankCardResponse 识别银行卡返回数据
  18. type BankCardResponse struct {
  19. CommonError
  20. Number string `json:"number"` // 银行卡号
  21. }
  22. // BankCardByURL 通过URL识别银行卡
  23. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  24. //
  25. // token 接口调用凭证
  26. // url 要检测的图片 url,传这个则不用传 img 参数。
  27. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  28. func BankCardByURL(token, cardURL string, mode RecognizeMode) (*BankCardResponse, error) {
  29. api := baseURL + apiBankcard
  30. return bankCardByURL(api, token, cardURL, mode)
  31. }
  32. func bankCardByURL(api, token, cardURL string, mode RecognizeMode) (*BankCardResponse, error) {
  33. res := new(BankCardResponse)
  34. err := ocrByURL(api, token, cardURL, mode, res)
  35. if err != nil {
  36. return nil, err
  37. }
  38. return res, nil
  39. }
  40. // BankCard 通过文件识别银行卡
  41. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  42. //
  43. // token 接口调用凭证
  44. // img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传递 img_url。
  45. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  46. func BankCard(token, filename string, mode RecognizeMode) (*BankCardResponse, error) {
  47. api := baseURL + apiBankcard
  48. return bankCard(api, token, filename, mode)
  49. }
  50. func bankCard(api, token, filename string, mode RecognizeMode) (*BankCardResponse, error) {
  51. res := new(BankCardResponse)
  52. err := ocrByFile(api, token, filename, mode, res)
  53. if err != nil {
  54. return nil, err
  55. }
  56. return res, err
  57. }
  58. // CardType 卡片方向
  59. type CardType = string
  60. // 所有卡片方向
  61. const (
  62. CardTypeFront = "Front" // 正面
  63. CardTypeBack = "Back" // 背面
  64. )
  65. // CardResponse 识别卡片返回数据
  66. type CardResponse struct {
  67. CommonError
  68. Type CardType `json:"type"` // 正面或背面,Front / Back
  69. ValidDate string `json:"valid_date"` // 有效期
  70. }
  71. // DrivingLicenseResponse 识别行驶证返回数据
  72. type DrivingLicenseResponse struct {
  73. CommonError
  74. IDNum string `json:"id_num"` // 证号
  75. Name string `json:"name"` // 姓名
  76. Nationality string `json:"nationality"` // 国家
  77. Sex string `json:"sex"` // 性别
  78. Address string `json:"address"` // 地址
  79. BirthDate string `json:"birth_date"` // 出生日期
  80. IssueDate string `json:"issue_date"` // 初次领证日期
  81. CarClass string `json:"car_class"` // 准驾车型
  82. ValidFrom string `json:"valid_from"` // 有效期限起始日
  83. ValidTo string `json:"valid_to"` // 有效期限终止日
  84. OfficialSeal string `json:"official_seal"` // 印章文构
  85. }
  86. // DriverLicenseByURL 通过URL识别行驶证
  87. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  88. //
  89. // token 接口调用凭证
  90. // url 要检测的图片 url,传这个则不用传 img 参数。
  91. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  92. func DriverLicenseByURL(token, licenseURL string) (*DrivingLicenseResponse, error) {
  93. api := baseURL + apiDrivingLicense
  94. return driverLicenseByURL(api, token, licenseURL)
  95. }
  96. func driverLicenseByURL(api, token, licenseURL string) (*DrivingLicenseResponse, error) {
  97. res := new(DrivingLicenseResponse)
  98. err := ocrByURL(api, token, licenseURL, "", res)
  99. if err != nil {
  100. return nil, err
  101. }
  102. return res, nil
  103. }
  104. // DriverLicense 通过文件识别行驶证
  105. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  106. //
  107. // token 接口调用凭证
  108. // img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传递 img_url。
  109. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  110. func DriverLicense(token, filename string) (*DrivingLicenseResponse, error) {
  111. api := baseURL + apiDrivingLicense
  112. return driverLicense(api, token, filename)
  113. }
  114. func driverLicense(api, token, filename string) (*DrivingLicenseResponse, error) {
  115. res := new(DrivingLicenseResponse)
  116. err := ocrByFile(api, token, filename, "", res)
  117. if err != nil {
  118. return nil, err
  119. }
  120. return res, err
  121. }
  122. // IDCardResponse 识别身份证返回数据
  123. type IDCardResponse = CardResponse
  124. // IDCardByURL 通过URL识别身份证
  125. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  126. //
  127. // token 接口调用凭证
  128. // url 要检测的图片 url,传这个则不用传 img 参数。
  129. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  130. func IDCardByURL(token, cardURL string, mode RecognizeMode) (*IDCardResponse, error) {
  131. api := baseURL + apiIDCard
  132. return idCardByURL(api, token, cardURL, mode)
  133. }
  134. func idCardByURL(api, token, cardURL string, mode RecognizeMode) (*IDCardResponse, error) {
  135. res := new(IDCardResponse)
  136. err := ocrByURL(api, token, cardURL, mode, res)
  137. if err != nil {
  138. return nil, err
  139. }
  140. return res, nil
  141. }
  142. // IDCard 通过文件识别身份证
  143. // 接口限制: 此接口需要提供对应小程序/公众号 appid,开通权限后方可调用。
  144. //
  145. // token 接口调用凭证
  146. // img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用传递 img_url。
  147. // mode 图片识别模式,photo(拍照模式)或 scan(扫描模式)
  148. func IDCard(token, filename string, mode RecognizeMode) (*IDCardResponse, error) {
  149. api := baseURL + apiIDCard
  150. return idCard(api, token, filename, mode)
  151. }
  152. func idCard(api, token, filename string, mode RecognizeMode) (*IDCardResponse, error) {
  153. res := new(IDCardResponse)
  154. err := ocrByFile(api, token, filename, mode, res)
  155. if err != nil {
  156. return nil, err
  157. }
  158. return res, err
  159. }
  160. // VehicleLicenseResponse 识别卡片返回数据
  161. type VehicleLicenseResponse struct {
  162. CommonError
  163. VehicleType string `json:"vehicle_type"`
  164. Owner string `json:"owner"`
  165. Addr string `json:"addr"`
  166. UseCharacter string `json:"use_character"`
  167. Model string `json:"model"`
  168. Vin string `json:"vin"`
  169. EngineNum string `json:"engine_num"`
  170. RegisterDate string `json:"register_date"`
  171. IssueDate string `json:"issue_date"`
  172. PlateNumB string `json:"plate_num_b"`
  173. Record string `json:"record"`
  174. PassengersNum string `json:"passengers_num"`
  175. TotalQuality string `json:"total_quality"`
  176. TotalprepareQualityQuality string `json:"totalprepare_quality_quality"`
  177. }
  178. // VehicleLicenseByURL 行驶证 OCR 识别
  179. func VehicleLicenseByURL(token, cardURL string, mode RecognizeMode) (*VehicleLicenseResponse, error) {
  180. api := baseURL + apiVehicleLicense
  181. return vehicleLicenseByURL(api, token, cardURL, mode)
  182. }
  183. func vehicleLicenseByURL(api, token, cardURL string, mode RecognizeMode) (*VehicleLicenseResponse, error) {
  184. res := new(VehicleLicenseResponse)
  185. err := ocrByURL(api, token, cardURL, mode, res)
  186. if err != nil {
  187. return nil, err
  188. }
  189. return res, nil
  190. }
  191. // VehicleLicense 通过文件识别行驶证
  192. func VehicleLicense(token, filename string, mode RecognizeMode) (*VehicleLicenseResponse, error) {
  193. api := baseURL + apiVehicleLicense
  194. return vehicleLicense(api, token, filename, mode)
  195. }
  196. func vehicleLicense(api, token, filename string, mode RecognizeMode) (*VehicleLicenseResponse, error) {
  197. res := new(VehicleLicenseResponse)
  198. err := ocrByFile(api, token, filename, mode, res)
  199. if err != nil {
  200. return nil, err
  201. }
  202. return res, err
  203. }
  204. // LicensePoint 证件点
  205. type LicensePoint struct {
  206. X uint `json:"x"`
  207. Y uint `json:"y"`
  208. }
  209. // LicensePosition 证件位置
  210. type LicensePosition struct {
  211. LeftTop LicensePoint `json:"left_top"`
  212. RightTop LicensePoint `json:"right_top"`
  213. RightBottom LicensePoint `json:"right_bottom"`
  214. LeftBottom LicensePoint `json:"left_bottom"`
  215. }
  216. // BusinessLicenseResponse 营业执照 OCR 识别返回数据
  217. type BusinessLicenseResponse struct {
  218. CommonError
  219. RegNum string `json:"reg_num"` // 注册号
  220. Serial string `json:"serial"` // 编号
  221. LegalRepresentative string `json:"legal_representative"` // 法定代表人姓名
  222. EnterpriseName string `json:"enterprise_name"` // 企业名称
  223. TypeOfOrganization string `json:"type_of_organization"` // 组成形式
  224. Address string `json:"address"` // 经营场所/企业住所
  225. TypeOfEnterprise string `json:"type_of_enterprise"` // 公司类型
  226. BusinessScope string `json:"business_scope"` // 经营范围
  227. RegisteredCapital string `json:"registered_capital"` // 注册资本
  228. PaidInCapital string `json:"paid_in_capital"` // 实收资本
  229. ValidPeriod string `json:"valid_period"` // 营业期限
  230. RegisteredDate string `json:"registered_date"` // 注册日期/成立日期
  231. CertPosition struct {
  232. Position LicensePosition `json:"pos"`
  233. } `json:"cert_position"` // 营业执照位置
  234. ImgSize LicensePoint `json:"img_size"` // 图片大小
  235. }
  236. // BusinessLicenseByURL 通过链接进行营业执照 OCR 识别
  237. func BusinessLicenseByURL(token, cardURL string) (*BusinessLicenseResponse, error) {
  238. api := baseURL + apiBusinessLicense
  239. return businessLicenseByURL(api, token, cardURL)
  240. }
  241. func businessLicenseByURL(api, token, cardURL string) (*BusinessLicenseResponse, error) {
  242. res := new(BusinessLicenseResponse)
  243. err := ocrByURL(api, token, cardURL, "", res)
  244. if err != nil {
  245. return nil, err
  246. }
  247. return res, nil
  248. }
  249. // BusinessLicense 通过文件进行营业执照 OCR 识别
  250. func BusinessLicense(token, filename string) (*BusinessLicenseResponse, error) {
  251. api := baseURL + apiBusinessLicense
  252. return businessLicense(api, token, filename)
  253. }
  254. func businessLicense(api, token, filename string) (*BusinessLicenseResponse, error) {
  255. res := new(BusinessLicenseResponse)
  256. err := ocrByFile(api, token, filename, "", res)
  257. if err != nil {
  258. return nil, err
  259. }
  260. return res, err
  261. }
  262. // PrintedTextResponse 通用印刷体 OCR 识别返回数据
  263. type PrintedTextResponse struct {
  264. CommonError
  265. Items []struct {
  266. Text string `json:"text"`
  267. Position LicensePosition `json:"pos"`
  268. } `json:"items"` // 识别结果
  269. ImgSize LicensePoint `json:"img_size"` // 图片大小
  270. }
  271. // PrintedTextByURL 通过链接进行通用印刷体 OCR 识别
  272. func PrintedTextByURL(token, cardURL string) (*PrintedTextResponse, error) {
  273. api := baseURL + apiPrintedText
  274. return printedTextByURL(api, token, cardURL)
  275. }
  276. func printedTextByURL(api, token, cardURL string) (*PrintedTextResponse, error) {
  277. res := new(PrintedTextResponse)
  278. err := ocrByURL(api, token, cardURL, "", res)
  279. if err != nil {
  280. return nil, err
  281. }
  282. return res, nil
  283. }
  284. // PrintedText 通过文件进行通用印刷体 OCR 识别
  285. func PrintedText(token, filename string) (*PrintedTextResponse, error) {
  286. api := baseURL + apiPrintedText
  287. return printedText(api, token, filename)
  288. }
  289. func printedText(api, token, filename string) (*PrintedTextResponse, error) {
  290. res := new(PrintedTextResponse)
  291. err := ocrByFile(api, token, filename, "", res)
  292. if err != nil {
  293. return nil, err
  294. }
  295. return res, err
  296. }
  297. func ocrByFile(api, token, filename string, mode RecognizeMode, response interface{}) error {
  298. queries := requestQueries{
  299. "access_token": token,
  300. "type": mode,
  301. }
  302. url, err := encodeURL(api, queries)
  303. if err != nil {
  304. return err
  305. }
  306. if err := postFormByFile(url, "img", filename, response); err != nil {
  307. return err
  308. }
  309. return nil
  310. }
  311. func ocrByURL(api, token, cardURL string, mode RecognizeMode, response interface{}) error {
  312. queries := requestQueries{
  313. "access_token": token,
  314. "img_url": cardURL,
  315. }
  316. if mode != "" {
  317. queries["type"] = mode
  318. }
  319. url, err := encodeURL(api, queries)
  320. if err != nil {
  321. return err
  322. }
  323. if err := postJSON(url, nil, response); err != nil {
  324. return err
  325. }
  326. return nil
  327. }