明经CAD社区

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
123
返回列表 发新帖
楼主: dcl1214

[源码] ocr图片识别研究

  [复制链接]
发表于 2024-5-9 22:47:36 | 显示全部楼层
edata 发表于 2023-6-10 16:32
大概率是ocr没有调用成功,没有获取到有效的字符串,导致建立多行文字的时候,使用了空字符串,你可以使 ...

长老,请问是是CAD折线文字重新输出图片然后WIN10 OCR文字到记事本然后又读取进来?
发表于 2024-5-10 09:40:48 | 显示全部楼层
是不是识别PDF转CAD后的文字,将断线文字复制识别到CAD?
发表于 2024-5-10 19:43:13 | 显示全部楼层
edata 发表于 2023-6-10 11:32
可以试试这个,https://github.com/zh-h/Windows.Media.Ocr.Cli


C:\>Windows.Media.Ocr.Cli.exe -o c:/1res.txt x2.png
ERROR: 字符串的长度不能为零。
参数名: oldValue
ERROR: 无法找不到组件。 (异常来自 HRESULT:0x88982F50)
能识别但不能导出,OS 名称:          Microsoft Windows 10 专业版
OS 版本:          10.0.19045 暂缺 Build 19045
OS 制造商:        Microsoft Corporation
OS 配置:          独立工作站
OS 构建类型:      Multiprocessor Free
发表于 2024-5-12 16:35:07 | 显示全部楼层
;(setq qz (vl-filename-mktemp "ocr" (getvar "SAVEFILEPATH")) ) ;前缀(vl-filename-mktemp "ocr" (getenv "temp"))

临时文件放临时保存文件夹较为合适,WIN10某些C盘不能读入写出文件,很烦,(getvar "SAVEFILEPATH") 保存到D盘
  OCR不认文件路径"\\",只是认识 正斜杠 于是又要替换 ljx-string-translate
  OCR放在CAD安装目录,反正又不大,,不用写路径直接如:(command "shell" Windows.Media.Ocr.Cli.exe  d:/temp/ocr004.png > d:/temp/ocr004.txt )
Windows.Media.Ocr.Cli.exe要把断线文字线条加宽,不然不认识,空却,还经常认错字,像我一样近视,不要抱太大期望

  1. ;;;;函数名称:  ljx-string-translate
  2. ;;;;调用格式:  (ljx-string-translate newtx oldtx str)
  3. ;;;;参数说明:  newtx ----- 要替换成的新字符
  4. ;;;;            oldtx-要替换的旧字符
  5. ;;;;            str  在str字符中替换      
  6. ;;;;返回值:  (ljx-string-translate "xx" "a" "123xxjkhxx") 返回""123ajkha""、
  7. ;;;;            (ljx-string-translate "xx" "" "123jkh")返回"1213jkh"
  8. ;;;;            newtx为""时相当于删除字符功能,非常好用
  9. ;;;;函数简介:  字符串替换函数,要替换的源字符与新字符长度可以不同,替换非常灵活好用            
  10. ;;;;函数来源:  原创
  11. ;;;;函数作者:  jixiangluo
  12. ;;;;适用版本:  不限
  13. ;;;;最后更新时  2019-08-03

  14. ;|(defun ljx-string-translate (newtx oldtx str / str1 i txz txy)
  15.   (setq str1 str)
  16.   (while (vl-string-search oldtx str1 )
  17.     (cond
  18.       ((= oldtx str1)
  19.        (setq str newtx)
  20.       )
  21.       ((= (vl-string-search oldtx str1) 0)
  22.        (setq i (+ (strlen oldtx) 1)
  23.        txy""
  24.        )
  25.        (repeat (- (strlen str1) (strlen oldtx))
  26.    (setq txy (strcat txy (substr str1 i 1))
  27.          i (1+ i)
  28.    )
  29.        );;;;repeat
  30.        (setq str (strcat newtx txy))
  31.       )
  32.       ((= (vl-string-search oldtx str1) (- (strlen str1) (strlen oldtx) 1))
  33.        (setq i 1
  34.        txz ""
  35.        )
  36.        (repeat (- (strlen str1) (strlen oldtx))
  37.    (setq txz (strcat txz (substr str1 i 1))
  38.          i (1+ i)
  39.    )
  40.        )
  41.        (setq str (strcat txz newtx))
  42.       )
  43.       (T
  44.        (setq i 1
  45.              txz ""
  46.        )
  47.        (repeat (vl-string-search oldtx str1)
  48.    (setq txz (strcat txz (substr str1 i 1))
  49.          i (1+ i)
  50.    )
  51.        );;;;repeat
  52.        (setq i (+ i (strlen oldtx))
  53.        txy ""
  54.        )
  55.        (repeat (- (strlen str1) i -1)
  56.    (setq txy (strcat txy (substr str1 i 1))
  57.          i (1+ i)
  58.          )
  59.        );;;;repeat
  60.        (setq str (strcat txz newtx txy))
  61.       )
  62.     );;;;cond
  63.     (setq str1 str)
  64.   );;;;while
  65.   str1
  66. );;;;defun|;

  67. (defun ljx-string-translate (newtx oldtx str / str1 strL oldL txt tx1 tx2 n1)
  68.   (setq str1 str
  69.   strL (strlen str1)
  70.   oldL (strlen oldtx)
  71.   txt ""
  72.   )
  73.   (while (setq n1 (vl-string-search oldtx str1 ))
  74.     (setq tx1 (substr str1 1 n1)
  75.     tx2 (substr str1 (+ n1 1 oldL) (- strL (strlen tx1) oldL))
  76.     txt (strcat txt tx1 newtx)
  77.     )
  78.     (setq str1 tx2
  79.     strL (strlen str1)
  80.     )
  81.   )
  82.   (setq txt (strcat txt str1))
  83. );;;;defun






  84. (defun lst->ss (lst / SS X)
  85.   ;图元转选择集
  86.   (if (and lst (setq lst (vl-remove nil lst))(setq
  87.          lst (VL-REMOVE-IF-NOT (FUNCTION (LAMBDA (A) (ENTGET A))) lst)
  88.        ))
  89.     (progn
  90.       (setq ss (ssadd))
  91.       (last
  92.     (mapcar(function(lambda (x) (ssadd x ss)))lst)
  93.       )
  94.     )
  95.   )
  96.   SS
  97. )

  98. (defun $ocr-dwg$ (ss  )
  99.   (setq qz (vl-filename-mktemp "ocr" (getvar "SAVEFILEPATH")) ) ;前缀(vl-filename-mktemp "ocr" (getenv "temp"))
  100.   (setq png-p (strcat qz ".png"))  ;图片文件名
  101.   (setq txt-p (strcat qz ".txt"))  ;txt文件名
  102.   ;(setq ss  (ssget ) )      ;提示用户框选pdf图元  SS在主函数中"_P"
  103.   (VL-CMDF "PNGOUT" png-p ss "") ;输出图片

  104.   (SETQ EXE-P (findfile "Windows.Media.Ocr.Cli.exe"))
  105. (vl-cmdf "shell" (strcat  "Windows.Media.Ocr.Cli.exe"  " " (ljx-string-translate "/" "\\" png-p) " " " > " (ljx-string-translate "/" "\\" txt-p) ))
  106.   
  107.   
  108.   
  109.   
  110.   (setq i 0)
  111.   (setq go t)
  112.   (while (and go (< i 200000000))  ;防止ocr软件保存txt时间不够,这里给定循环时间
  113.     (if (setq f (vl-catch-all-apply 'open (list txt-p "r")))
  114.           ;开启txt文件准备读取字串
  115.       (while
  116.         (setq str (vl-catch-all-apply 'read-line (list f)))
  117.           ;逐行读取
  118.          (if str
  119.      (setq go nil)
  120.          )      ;一旦读取到了字串就让while结束循环
  121.          (setq strs (cons str strs)) ;字串记录
  122.       )
  123.     )
  124.     (vl-catch-all-apply 'close (list f)) ;关闭文件
  125.     (setq i (1+ i))
  126.   )
  127.   (setq strs (vl-remove '"" strs)) ;删除空行
  128.   (setq strs (reverse strs))  ;颠倒过来
  129.       
  130.    
  131.   
  132.   (and ss(setq ents(vl-remove-if(function listp)(mapcar (function cadr) (ssnamex SS)))));选择集转图元
  133.   (setq jbs(mapcar(function(lambda(a)(cdr(assoc 5(entget a)))))ents));获取句柄
  134.   (if ss(SETQ BOX (getbox SS NIL)))
  135.   (vl-catch-all-apply 'vl-file-delete (list png-p)) ;删除图片文件
  136.   (vl-catch-all-apply 'vl-file-delete (list txt-p)) ;删除txt文件
  137.   (setq ss nil)
  138.   (LIST (CONS "坐标" BOX) (cons "字串" strs)(cons "图元句柄" jbs));返回
  139. )

  140. (defun getbox (xzj         QJBLM           /             i               xdir
  141.                ydir         zdir           origin    wcsOrg    UcsFlag
  142.                matLst         matrix           revMat    sel       ent
  143.                obj         minPt           maxPt     minLs     maxLs
  144.                maxX         maxY           minX             minY
  145.                Make-Rectange-getbox             dxf $GetMatrix$
  146.               )
  147. ;;; ;诡异的填充
  148.                                         ;(ENTMAKE (QUOTE ((0 . HATCH) (100 . AcDbEntity) (100 . AcDbHatch) (10 0.0 0.0 0.0) (210 0.0 0.0 1.0) (2 . SOLID) (70 . 1) (71 . 0) (91 . 1) (92 . 1) (93 . 1) (72 . 2) (10 3.67321e-006 -1.0 0.0) (40 . 1.0) (50 . 1.5708) (51 . 1.5708) (73 . 1) (97 . 0) (75 . 0) (76 . 1) (98 . 1) (10 97.2 305.1 0.0))))会导致外包围错误
  149.   ;;先判断UCS是否与WCS相同。如是则取得UCS的X方向,
  150.   ;;Y方向,Z方向,UCS原点及WCS的原点相对UCS的坐标点
  151.   ;;然后得到UCS变换矩阵和到WCS的逆变换矩阵
  152.                                         ;QJBLM  全局使用的变量名(字符串格式),这个将作为全局变量名供很多地方调用
  153.   (defun Make-Rectange-getbox (PTT1 PTT2 QJBLM)
  154. ;;;    ;构造矩形
  155. ;;;    (IF (/= $EF-tzqy(vl-princ-to-string(list(list (car PTT1) (cadr PTT1))(list (car PTT2) (cadr PTT1))(list (car PTT2) (cadr PTT2))(list (car PTT1) (cadr PTT2)))))(ALERT "变了哦"))
  156.     (set (read QJBLM)
  157.          (vl-princ-to-string
  158.            (list (list (car PTT1) (cadr PTT1))
  159.                  (list (car PTT2) (cadr PTT1))
  160.                  (list (car PTT2) (cadr PTT2))
  161.                  (list (car PTT1) (cadr PTT2))
  162.            )
  163.          )                                ;将坐标点赋值给QJBLM
  164.     )
  165. ;;;  (TTEDIT (entlast) "zx-tzqy" (cons 1000 (vl-princ-to-string(list(list (car PTT1) (cadr PTT1))(list (car PTT2) (cadr PTT1))(list (car PTT2) (cadr PTT2))(list (car PTT1) (cadr PTT2))))) "del")
  166.   )
  167.   (defun $GetMatrix$ (lst org Revflag / mat i j)
  168.   (setq mat (vlax-make-safearray vlax-vbDouble '(0 . 3) '(0 . 3)))
  169.                                         ;初始化一个4X4的矩阵
  170.   (setq i 0)
  171.   (repeat 3
  172.     (vlax-safearray-put-element mat i 3 (nth i org)) ;平移变换
  173.     (setq j 0)
  174.     (repeat 3
  175.       (if RevFlag
  176.         (vlax-safearray-put-element mat i j (nth j (nth i lst)))
  177.                                         ;角度逆变换
  178.         (vlax-safearray-put-element mat i j (nth i (nth j lst)))
  179.                                         ;角度的变换
  180.       )
  181.       (setq j (1+ j))
  182.     )
  183.     (setq i (1+ i))
  184.   )
  185.   (vlax-safearray-put-element mat 3 3 1)
  186.   mat                                        ;返回矩阵
  187. )
  188.   (defun G:CrossProductor        (vec1 vec2 / a b c d e f)
  189.   ;;;   ;两矢量的叉积
  190.   (setq a (car vec1))
  191.   (setq b (cadr vec1))
  192.   (setq c (caddr vec1))
  193.   (setq d (car vec2))
  194.   (setq e (cadr vec2))
  195.   (setq f (caddr vec2))
  196.   (list
  197.     (- (* b f) (* c e))
  198.     (- (* c d) (* a f))
  199.     (- (* a e) (* b d))
  200.   )
  201. )
  202.   (if (and
  203.         xzj
  204.         (or (and (= (TYPE XZJ) 'VLA-OBJECT) (SETQ XZJ (LST->SS (LIST (vlax-vla-object->ename XZJ)))))
  205.             (and (= (TYPE XZJ) 'ENAME) (SETQ XZJ (LST->SS (LIST XZJ))))
  206.                                         ;如果传递进来的是一个图元,就自动转换一下
  207.             (and (= (TYPE XZJ) 'list)
  208.                  (= (TYPE (car XZJ)) 'ENAME)
  209.                  (SETQ XZJ (LST->SS xzj))
  210.             )                                ;如果传递进来是一个图元列表ss,就自动转换选择集
  211.             t
  212.         )
  213.         (= (type xzj) 'pickset)
  214.         (or (and qjblm (= (type qjblm) 'str) (> (strlen qjblm) 1))
  215.             (not qjblm)
  216.         )
  217.       )
  218.     (progn
  219.       (setq UcsFlag (getvar "WORLDUCS"))
  220.       (if (= UcsFlag 0)                        ;UCS是否与WCS相同
  221.         (setq UcsFlag T                        ;设置标志位为true
  222.               xdir    (getvar "UCSXDIR") ;X方向矢量
  223.               ydir    (getvar "UCSYDIR") ;Y方向矢量
  224.               zdir    (G:CrossProductor xdir ydir)
  225.                                         ;X和Y的方向矢量的叉积
  226.               origin  (getvar "UCSORG")        ;原点
  227.               WcsOrg  (trans '(0 0 0) 0 1) ;WCS的原点相对UCS的坐标
  228.               matLst  (list xdir ydir zdir) ;旋转的变换矩阵表
  229.               matrix  ($GetMatrix$ matLst origin nil)
  230.                                         ;从WCS到UCS的变换矩阵
  231.               revMat  ($GetMatrix$ matLst WcsOrg T) ;从UCS到WCS的变换矩阵
  232.         )
  233.         (setq UcsFlag nil)                ;否则不予变换
  234.       )
  235.       ;;在UCS下先变换物体到WCS下,取得每个物体的包围框,
  236.       ;;求出包围框集合的最小XY,最大XY,并用矩形框画出来
  237.       ;;然后把物体变换回到UCS,并把矩形也变换回去
  238.       (if (setq sel xzj)
  239.         ;;选择物体
  240.         (progn
  241.           (setq i 0)
  242.           (setq minPt (vlax-make-safearray vlax-vbdouble '(0 . 2)))
  243.                                         ;左下角点
  244.           (setq maxPt (vlax-make-safearray vlax-vbdouble '(0 . 2)))
  245.                                         ;右上角点
  246.           (repeat (sslength sel)
  247.             (if        (and (setq dxf nil
  248.                            dxf (entget (setq ent (ssname sel i)))
  249.                      )                        ;图元
  250.                      (or (AND (WCMATCH (CDR (ASSOC 0 DXF)) "*TEXT")
  251.                               (WCMATCH (CDR (ASSOC 1 DXF)) "[, ,,]")
  252.                                         ;空格或者是空值“”
  253.                          )                ;如果一个空格文字的话                        
  254.                          (and (= (cdr (assoc 0 dxf)) "HATCH")
  255.                               (= (cdr (assoc 93 dxf)) 1)
  256.                          )                ;反正93等于1的时候不能创建填充,但是遇到诡异的填充,93等于1就可以创建,既然93在诡异的情况下可以创建,那就用93=1来排除它,诡异的填充在这里:;(ENTMAKE (QUOTE ((0 . HATCH) (100 . AcDbEntity) (100 . AcDbHatch) (10 0.0 0.0 0.0) (210 0.0 0.0 1.0) (2 . SOLID) (70 . 1) (71 . 0) (91 . 1) (92 . 1) (93 . 1) (72 . 2) (10 3.67321e-006 -1.0 0.0) (40 . 1.0) (50 . 1.5708) (51 . 1.5708) (73 . 1) (97 . 0) (75 . 0) (76 . 1) (98 . 1) (10 97.2 305.1 0.0))))
  257.                      )
  258.                 )
  259.               ()                        ;以上条件成立以后,啥也不敢干呀
  260.               (PROGN
  261.                 (setq obj (vlax-ename->vla-object ent)) ;obj对象
  262.                 (and UcsFlag (vla-TransformBy obj revMat))
  263.                                         ;反变换到WCS
  264. ;;;                    (vla-GetBoundingBox obj 'minpt 'maxpt)
  265.                 (and (not (vl-catch-all-error-p
  266.                             (vl-catch-all-apply
  267.                               'vla-GetBoundingBox
  268.                               (list obj 'minPt 'maxPt)
  269.                             )
  270.                           )
  271.                      )                        ;得到包围框
  272.                      (setq minPt (vlax-safearray->list minPt))
  273.                      (setq maxPt (vlax-safearray->list maxPt))
  274.                      (setq minLs (cons minPt minLs)) ;得到左下角点表
  275.                      (setq maxLs (cons maxPt maxLs)) ;得到右上角点表
  276.                 )
  277.                 (and UcsFlag (vla-TransformBy obj matrix))
  278.                                         ;变换回到UCS
  279.               )
  280.             )
  281.             (setq i (1+ i))
  282.           )
  283.           (and minLs
  284.                (setq minX (apply 'min (mapcar 'car minLs)))
  285.                                         ;最小点集的最小X
  286.                (setq minY (apply 'min (mapcar 'cadr minLs)))
  287.                                         ;最小点集的最小Y
  288.           )
  289.           (and maxLs
  290.                (setq maxX (apply 'max (mapcar 'car maxLs)))
  291.                                         ;最大点集的最小X
  292.                (setq maxY (apply 'max (mapcar 'cadr maxLs)))
  293.                                         ;最打点集的最小Y
  294.           )
  295.           (and QJBLM
  296.                (Make-Rectange-getbox
  297.                  (list minX minY 0)
  298.                  (list maxX maxY 0)
  299.                  QJBLM
  300.                )
  301.           )                                ;构造边框
  302. ;;;          (and                                
  303. ;;;            UcsFlag                        ;如果UCS的话
  304. ;;;            (vla-TransformBy
  305. ;;;              (vlax-ename->vla-object (entlast))
  306. ;;;              matrix                        ;变换边框到UCS
  307. ;;;            )
  308. ;;;          )
  309.         )
  310.       )
  311.     )
  312.   )
  313.   (IF (AND minX minY maxX maxY)
  314.     (list (list minX minY 0) (list maxX maxY 0))
  315.   )
  316. )
  317. (defun c:ocr123 (/ 1/2p 1/2p-n bl box box-new ent ents html jbs l obj result s sbjg ss str strs)
  318.   (setq sbjg ($ocr-dwg$ (ssget)))
  319.   (SETQ BOX(CDR(ASSOC "坐标" sbjg)))
  320.   (setq strs (cdr (assoc "字串" sbjg)))
  321.   (if strs
  322.     (progn
  323.        (setq jbs(cdr(assoc "图元句柄" sbjg)))
  324.   (setq ents(mapcar 'handent jbs))
  325.   (setq ss (ssadd))
  326.   (mapcar(function(lambda (x) (ssadd x ss)))ents)
  327.   (if ss(vl-cmdf "change" ss "" "P" "C" 1 ""))
  328.   (setq ss nil)
  329.   (setq s nil)
  330.   (while (setq str (car strs))
  331.     (if  s
  332.       (setq s (strcat s "\n" str))
  333.       (setq s str)
  334.     )
  335.     (setq strs (cdr strs))
  336.   )
  337.   (setq str s)
  338.   (SETQ L(ABS(APPLY '-(MAPCAR 'CAR BOX))))
  339.   (SETQ L(* L 0.8))
  340.   (setq OBJ (vla-addmtext(vla-get-modelSpace(vla-get-ActiveDocument (vlax-get-acad-object)))(vlax-3d-point (list 0 0 0))(vlax-make-variant L 5)str))  
  341.   (SETQ ENT(VLAX-VLA-OBJECT->ENAME OBJ))
  342.   (SETQ BOX-NEW(GETBOX ENT NIL))
  343.   (SETQ BL(/(ABS(distance(car BOX)(cadr box)))(ABS(distance(car BOX-NEW)(cadr BOX-NEW)))))
  344.   (setq 1/2p(mapcar(function(lambda(x y)(* (+ x y)0.5)))(car BOX)(cadr BOX)))
  345.   (setq 1/2p-n(mapcar(function(lambda(x y)(* (+ x y)0.5)))(car BOX-NEW)(cadr BOX-NEW)))
  346.   (vla-ScaleEntity OBJ(vlax-3D-point 1/2p-n)bl)
  347.   (vla-move obj (vlax-3d-point 1/2p-n) (vlax-3d-point 1/2p))
  348.        (setq  html   (vlax-create-object "htmlfile")
  349.   result (vlax-invoke
  350.      (vlax-get (vlax-get html 'ParentWindow)
  351.          'ClipBoardData
  352.      )
  353.      'setData
  354.      "Text"
  355.      str
  356.          )
  357.   )
  358.   (vlax-release-object html)
  359.     )
  360.   )

  361. obj
  362. )


评分

参与人数 1明经币 +1 收起 理由
自贡黄明儒 + 1

查看全部评分

发表于 2024-5-12 16:53:48 | 显示全部楼层
树櫴希德 发表于 2024-5-12 16:35
;(setq qz (vl-filename-mktemp "ocr" (getvar "SAVEFILEPATH")) ) ;前缀(vl-filename-mktemp "ocr" (gete ...

这可是新东西,先给您点赞,等有兴趣了再来玩。
发表于 2024-5-12 18:09:59 | 显示全部楼层
自贡黄明儒 发表于 2024-5-12 16:53
这可是新东西,先给您点赞,等有兴趣了再来玩。

谢谢黄教授
发表于 2024-10-19 10:01:42 | 显示全部楼层
我运行后,选择PDF转过来的被打散的文字,卡死。
发表于 2024-10-19 20:17:06 | 显示全部楼层
学习了,有机会研究一下看看
您需要登录后才可以回帖 登录 | 注册

本版积分规则

小黑屋|手机版|CAD论坛|CAD教程|CAD下载|联系我们|关于明经|明经通道 ( 粤ICP备05003914号 )  
©2000-2023 明经通道 版权所有 本站代码,在未取得本站及作者授权的情况下,不得用于商业用途

GMT+8, 2025-2-22 02:20 , Processed in 1.140448 second(s), 22 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表