婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > python中opencv實現文字分割的實踐

python中opencv實現文字分割的實踐

熱門標簽:佛山400電話辦理 儋州電話機器人 地圖標注面積 小蘇云呼電話機器人 朝陽手機外呼系統 北京電銷外呼系統加盟 市場上的電銷機器人 所得系統電梯怎樣主板設置外呼 北瀚ai電銷機器人官網手機版

圖片文字分割的時候,常用的方法有兩種。一種是投影法,適用于排版工整,字間距行間距比較寬裕的圖像;還有一種是用OpenCV的輪廓檢測,適用于文字不規則排列的圖像。

投影法

對文字圖片作橫向和縱向投影,即通過統計出每一行像素個數,和每一列像素個數,來分割文字。
分別在水平和垂直方向對預處理(二值化)的圖像某一種像素進行統計,對于二值化圖像非黑即白,我們通過對其中的白點或者黑點進行統計,根據統計結果就可以判斷出每一行的上下邊界以及每一列的左右邊界,從而實現分割的目的。

算法步驟:

  • 使用水平投影和垂直投影的方式進行圖像分割,根據投影的區域大小尺寸分割每行和每塊的區域,對原始圖像進行二值化處理。
  • 投影之前進行圖像灰度學調整做膨脹操作
  • 分別進行水平投影和垂直投影
  • 根據投影的長度和高度求取完整行和塊信息

橫板文字-小票文字分割

#小票水平分割
import cv2
import numpy as np

img = cv2.imread(r"C:\Users\An\Pictures\1.jpg")
cv2.imshow("Orig Image", img)
# 輸出圖像尺寸和通道信息
sp = img.shape
print("圖像信息:", sp)
sz1 = sp[0]  # height(rows) of image
sz2 = sp[1]  # width(columns) of image
sz3 = sp[2]  # the pixels value is made up of three primary colors
print('width: %d \n height: %d \n number: %d' % (sz2, sz1, sz3))
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
retval, threshold_img = cv2.threshold(gray_img, 120, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("threshold_img", threshold_img)

# 水平投影分割圖像
gray_value_x = []
for i in range(sz1):
    white_value = 0
    for j in range(sz2):
        if threshold_img[i, j] == 255:
            white_value += 1
    gray_value_x.append(white_value)
print("", gray_value_x)
# 創建圖像顯示水平投影分割圖像結果
hori_projection_img = np.zeros((sp[0], sp[1], 1), np.uint8)
for i in range(sz1):
    for j in range(gray_value_x[i]):
        hori_projection_img[i, j] = 255
cv2.imshow("hori_projection_img", hori_projection_img)
text_rect = []
# 根據水平投影分割識別行
inline_x = 0
start_x = 0
text_rect_x = []
for i in range(len(gray_value_x)):
    if inline_x == 0 and gray_value_x[i] > 10:
        inline_x = 1
        start_x = i
    elif inline_x == 1 and gray_value_x[i]  10 and (i - start_x) > 5:
        inline_x = 0
        if i - start_x > 10:
            rect = [start_x - 1, i + 1]
            text_rect_x.append(rect)
print("分行區域,每行數據起始位置Y:", text_rect_x)
# 每行數據分段
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 3))
dilate_img = cv2.dilate(threshold_img, kernel)
cv2.imshow("dilate_img", dilate_img)
for rect in text_rect_x:
    cropImg = dilate_img[rect[0]:rect[1],0:sp[1]]  # 裁剪圖像y-start:y-end,x-start:x-end
    sp_y = cropImg.shape
    # 垂直投影分割圖像
    gray_value_y = []
    for i in range(sp_y[1]):
        white_value = 0
        for j in range(sp_y[0]):
            if cropImg[j, i] == 255:
                white_value += 1
        gray_value_y.append(white_value)
    # 創建圖像顯示水平投影分割圖像結果
    veri_projection_img = np.zeros((sp_y[0], sp_y[1], 1), np.uint8)
    for i in range(sp_y[1]):
        for j in range(gray_value_y[i]):
            veri_projection_img[j, i] = 255
    cv2.imshow("veri_projection_img", veri_projection_img)
    # 根據垂直投影分割識別行
    inline_y = 0
    start_y = 0
    text_rect_y = []
    for i in range(len(gray_value_y)):
        if inline_y == 0 and gray_value_y[i] > 2:
            inline_y = 1
            start_y = i
        elif inline_y == 1 and gray_value_y[i]  2 and (i - start_y) > 5:
            inline_y = 0
            if i - start_y > 10:
                rect_y = [start_y - 1, i + 1]
                text_rect_y.append(rect_y)
                text_rect.append([rect[0], rect[1], start_y - 1, i + 1])
                cropImg_rect = threshold_img[rect[0]:rect[1], start_y - 1:i + 1]  # 裁剪圖像
                cv2.imshow("cropImg_rect", cropImg_rect)
                # cv2.imwrite("C:/Users/ThinkPad/Desktop/cropImg_rect.jpg",cropImg_rect)
                # break
        # break
# 在原圖上繪制截圖矩形區域
print("截取矩形區域(y-start:y-end,x-start:x-end):", text_rect)
rectangle_img = cv2.rectangle(img, (text_rect[0][2], text_rect[0][0]), (text_rect[0][3], text_rect[0][1]),
                              (255, 0, 0), thickness=1)
for rect_roi in text_rect:
    rectangle_img = cv2.rectangle(img, (rect_roi[2], rect_roi[0]), (rect_roi[3], rect_roi[1]), (255, 0, 0), thickness=1)
cv2.imshow("Rectangle Image", rectangle_img)

key = cv2.waitKey(0)
if key == 27:
    print(key)
    cv2.destroyAllWindows()

小票圖像二值化結果如下:

小票圖像結果分割如下:

豎版-古文文字分割

對于古籍來說,古籍文字書寫在習慣是從上到下的,所以說在掃描的時候應該掃描列投影,在掃描行投影。

1.原始圖像進行二值化

使用水平投影和垂直投影的方式進行圖像分割,根據投影的區域大小尺寸分割每行和每塊的區域,對原始圖像進行二值化處理。

原始圖像:


二值化后的圖像:

2.圖像膨脹

投影之前進行圖像灰度學調整做膨脹操作,選取適當的核,對圖像進行膨脹處理。

3.垂直投影

定位該行文字區域:
數值不為0的區域就是文字存在的地方(即二值化后白色部分的區域),為0的區域就是每行之間相隔的距離。
1、如果前一個數為0,則記錄第一個不為0的坐標。
2、如果前一個數不為0,則記錄第一個為0的坐標。形象的說就是從出現第一個非空白列到出現第一個空白列這段區域就是文字存在的區域。
通過以上規則就可以找出每一列文字的起始點和終止點,從而確定每一列的位置信息。

垂直投影結果:


通過上面的垂直投影,根據其白色小山峰的起始位置就可以界定出每一列的起始位置,從而把每一列分割出來。

4.水平投影

根據投影的長度和高度求取完整行和塊信息
通過水平投影可以獲得每一個字符左右的起始位置,這樣也就可以獲得到每一個字符的具體坐標位置,即一個矩形框的位置。

import cv2
import numpy as np
import os

img = cv2.imread(r"C:\Users\An\Pictures\3.jpg")
save_path=r"E:\crop_img\result" #圖像分解的每一步保存的地址
crop_path=r"E:\crop_img\img" #圖像切割保存的地址
cv2.imshow("Orig Image", img)
# 輸出圖像尺寸和通道信息
sp = img.shape
print("圖像信息:", sp)
sz1 = sp[0]  # height(rows) of image
sz2 = sp[1]  # width(columns) of image
sz3 = sp[2]  # the pixels value is made up of three primary colors
print('width: %d \n height: %d \n number: %d' % (sz2, sz1, sz3))
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
retval, threshold_img = cv2.threshold(gray_img, 120, 255, cv2.THRESH_BINARY_INV)
cv2.imshow("threshold_img", threshold_img)
cv2.imwrite(os.path.join(save_path,"threshold_img.jpg"),threshold_img)

# 垂直投影分割圖像
gray_value_y = []
for i in range(sz2):
    white_value = 0
    for j in range(sz1):
        if threshold_img[j, i] == 255:
            white_value += 1
    gray_value_y.append(white_value)
print("", gray_value_y)
#創建圖像顯示垂直投影分割圖像結果
veri_projection_img = np.zeros((sp[0], sp[1], 1), np.uint8)
for i in range(sz2):
    for j in range(gray_value_y[i]):
        veri_projection_img[j, i] = 255
cv2.imshow("veri_projection_img", veri_projection_img)
cv2.imwrite(os.path.join(save_path,"veri_projection_img.jpg"),veri_projection_img)
text_rect = []


# 根據垂直投影分割識別列
inline_y = 0
start_y = 0
text_rect_y = []
for i in range(len(gray_value_y)):
    if inline_y == 0 and gray_value_y[i]> 30:
        inline_y = 1
        start_y = i
    elif inline_y == 1 and gray_value_y[i]  30 and (i - start_y) > 5:
        inline_y = 0
        if i - start_y > 10:
            rect = [start_y - 1, i + 1]
            text_rect_y.append(rect)
print("分列區域,每列數據起始位置Y:", text_rect_y)
# 每列數據分段
# kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (13, 3))
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
dilate_img = cv2.dilate(threshold_img, kernel)
cv2.imshow("dilate_img", dilate_img)
cv2.imwrite(os.path.join(save_path,"dilate_img.jpg"),dilate_img)
for rect in text_rect_y:
    cropImg = dilate_img[0:sp[0],rect[0]:rect[1]]  # 裁剪圖像y-start:y-end,x-start:x-end
    sp_x = cropImg.shape
    # 垂直投影分割圖像
    gray_value_x = []
    for i in range(sp_x[0]):
        white_value = 0
        for j in range(sp_x[1]):
            if cropImg[i, j] == 255:
                white_value += 1
        gray_value_x.append(white_value)
    # 創建圖像顯示水平投影分割圖像結果
    hori_projection_img = np.zeros((sp_x[0], sp_x[1], 1), np.uint8)
    for i in range(sp_x[0]):
        for j in range(gray_value_x[i]):
            veri_projection_img[i, j] = 255
    # cv2.imshow("hori_projection_img", hori_projection_img)
    # 根據水平投影分割識別行
    inline_x = 0
    start_x = 0
    text_rect_x = []
    ind=0
    for i in range(len(gray_value_x)):
        ind+=1
        if inline_x == 0 and gray_value_x[i] > 2:
            inline_x = 1
            start_x = i
        elif inline_x == 1 and gray_value_x[i]  2 and (i - start_x) > 5:
            inline_x = 0
            if i - start_x > 10:
                rect_x = [start_x - 1, i + 1]
                text_rect_x.append(rect_x)
                text_rect.append([start_x - 1, i + 1,rect[0], rect[1]])
                cropImg_rect = threshold_img[start_x - 1:i + 1,rect[0]:rect[1]]  # 裁剪二值化圖像
                crop_img=img[start_x - 1:i + 1,rect[0]:rect[1]] #裁剪原圖像
                # cv2.imshow("cropImg_rect", cropImg_rect)
                # cv2.imwrite(os.path.join(crop_path,str(ind)+".jpg"),crop_img)
                # break
        # break
# 在原圖上繪制截圖矩形區域
print("截取矩形區域(y-start:y-end,x-start:x-end):", text_rect)
rectangle_img = cv2.rectangle(img, (text_rect[0][2], text_rect[0][0]), (text_rect[0][3], text_rect[0][1]),
                              (255, 0, 0), thickness=1)
for rect_roi in text_rect:
    rectangle_img = cv2.rectangle(img, (rect_roi[2], rect_roi[0]), (rect_roi[3], rect_roi[1]), (255, 0, 0), thickness=1)
cv2.imshow("Rectangle Image", rectangle_img)
cv2.imwrite(os.path.join(save_path,"rectangle_img.jpg"),rectangle_img)
key = cv2.waitKey(0)
if key == 27:
    print(key)
    cv2.destroyAllWindows()

分割結果如下:

從分割的結果上看,基本上實現了圖片中文字的分割。但由于中文結構復雜性,對于一些文字的分割并不理想,字會出現過度分割、有粘連的兩個字會出現分割不夠的現象。可以從圖像預處理(圖像腐蝕膨脹),邊界判斷閾值的調整等方面進行優化。

到此這篇關于python中opencv實現文字分割的實踐的文章就介紹到這了,更多相關opencv 文字分割內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • Python+opencv 實現圖片文字的分割的方法示例

標簽:商丘 寧夏 江蘇 定西 酒泉 金融催收 云南 龍巖

巨人網絡通訊聲明:本文標題《python中opencv實現文字分割的實踐》,本文關鍵詞  python,中,opencv,實現,文字,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《python中opencv實現文字分割的實踐》相關的同類信息!
  • 本頁收集關于python中opencv實現文字分割的實踐的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    91精品国产综合久久久久久久| 亚洲精品中文字幕乱码三区| 国产视频一区在线观看| 欧美va在线播放| 国产亚洲精品超碰| 99久久婷婷国产| 欧美伊人精品成人久久综合97| 国产亚洲视频系列| 午夜欧美在线一二页| 亚洲精品高清视频在线观看| 亚洲国产另类精品专区| 成人avav影音| 国产成人日日夜夜| 亚洲女子a中天字幕| 成人高清av在线| 国产最新精品免费| 五月婷婷色综合| 国产大片一区二区| 另类小说综合欧美亚洲| 在线播放欧美女士性生活| 亚洲一区二区在线播放相泽| 亚洲欧美日韩小说| 成人免费观看视频| 亚洲天堂成人在线观看| 成人的网站免费观看| 日韩高清电影一区| 亚洲欧美日韩在线播放| 中文字幕人成不卡一区| 丝袜美腿亚洲一区二区图片| 久久在线免费观看| 69堂成人精品免费视频| 亚洲国产日韩在线一区模特| 国产色爱av资源综合区| 亚洲国产精品成人久久综合一区| 国产在线观看一区二区| 欧美电影免费观看高清完整版| 一本一道久久a久久精品| 日韩在线一区二区三区| 久久久噜噜噜久久中文字幕色伊伊 | 91无套直看片红桃| 国产蜜臀av在线一区二区三区| 成人黄色软件下载| 国产**成人网毛片九色| 九色porny丨国产精品| 欧美年轻男男videosbes| jlzzjlzz亚洲日本少妇| 黄页视频在线91| 91香蕉国产在线观看软件| 欧美怡红院视频| 国产成人综合网| 欧美丰满少妇xxxbbb| 精品欧美一区二区三区精品久久| 97久久超碰国产精品| 欧美高清视频不卡网| 精品久久久久久久久久久院品网 | 亚洲图片激情小说| 欧美一区二区三区在线电影| 色呦呦日韩精品| 色妞www精品视频| 国产精品一区免费视频| 日本一区二区三区在线不卡| 精品国产亚洲在线| 国产精品嫩草久久久久| 久久亚洲春色中文字幕久久久| 国产欧美一区二区精品久导航 | 色综合色狠狠天天综合色| 在线免费观看日本欧美| 欧美成人在线直播| av中文一区二区三区| 91麻豆精品国产91久久久久久久久| 欧美日韩亚洲丝袜制服| 亚洲视频一区二区免费在线观看| 久久精品视频一区二区| 奇米四色…亚洲| 欧洲中文字幕精品| 欧美成人精品福利| 亚洲地区一二三色| 精品国产污污免费网站入口 | 亚洲美女在线国产| 欧美一区二区三区四区五区| 国产一区二区三区美女| 激情亚洲综合在线| 国产白丝精品91爽爽久久| 亚洲一区欧美一区| 国产成人精品免费看| 亚洲精品水蜜桃| 精品久久久久久久人人人人传媒| 成人动漫精品一区二区| 亚洲欧美在线高清| 一区二区三区日韩欧美| 久久久国产午夜精品| 欧美日韩国产影片| 99久久综合狠狠综合久久| 99久久国产免费看| 91国偷自产一区二区开放时间 | 欧美精品乱人伦久久久久久| 国产成人亚洲精品青草天美| 亚洲va国产va欧美va观看| 久久99精品久久久久久国产越南| 亚洲人成在线播放网站岛国| 久久精品国产一区二区| 国产亚洲婷婷免费| 美脚の诱脚舐め脚责91| 国产麻豆成人精品| 成人动漫av在线| 亚洲精品五月天| 亚洲色图.com| 国产在线播放一区| 中文字幕av不卡| 欧美一级一区二区| 亚洲黄色免费电影| 26uuu另类欧美| 国产精品一区免费在线观看| 综合欧美亚洲日本| 色综合亚洲欧洲| 国产精品久久久久久久岛一牛影视| 精品国产91亚洲一区二区三区婷婷| 日韩 欧美一区二区三区| 成人精品高清在线| 91美女片黄在线| 欧美日韩精品欧美日韩精品| 99国产精品国产精品毛片| 国产成人精品影视| 日本成人在线视频网站| 黄色日韩网站视频| 99久久国产免费看| 欧美一区二区网站| 欧美tk—视频vk| 国产亚洲精品7777| 日日夜夜精品视频免费| 国产精品一区二区在线看| 欧美亚洲动漫另类| 亚洲欧美在线观看| 国产精品系列在线播放| 欧美日本一区二区三区四区| 国产情人综合久久777777| 夜夜嗨av一区二区三区四季av| 国产精品中文字幕日韩精品| 欧美亚洲自拍偷拍| 久久久精品免费免费| 97精品久久久午夜一区二区三区| 99视频热这里只有精品免费| 日韩欧美国产成人一区二区| 国产精品视频一二三| 欧美美女网站色| 国产精品久久久久久久久图文区| 亚洲一卡二卡三卡四卡| www.在线成人| 精品免费一区二区三区| 国产喂奶挤奶一区二区三区| 国产精品视频yy9299一区| 91国模大尺度私拍在线视频| 免费看欧美美女黄的网站| 国产精品日韩成人| 欧美妇女性影城| 成人黄色大片在线观看| 日韩av中文在线观看| 日韩三级.com| 国产一区二区三区日韩 | 91免费在线视频观看| 在线不卡中文字幕播放| 日韩美女视频一区| 精品国产自在久精品国产| 日韩精品免费视频人成| 一区二区三区视频在线看| 国产成人亚洲精品狼色在线| 久久午夜免费电影| 麻豆91精品视频| 久久伊人中文字幕| 国产精品三级视频| 91高清视频在线| 色成人在线视频| 亚洲日本韩国一区| 欧美日韩二区三区| 九色综合狠狠综合久久| 精品国产亚洲在线| 成人永久免费视频| 一区二区视频在线| 久久香蕉国产线看观看99| 色婷婷av一区二区三区gif| 奇米影视在线99精品| 久久久国产精品麻豆| 欧美日韩的一区二区| 国产精品99久久久久久久vr| 亚洲美女区一区| 欧美极品少妇xxxxⅹ高跟鞋| 欧美日韩一区二区三区免费看| 国产一区二区三区四| 亚洲日本青草视频在线怡红院| 亚洲欧美日韩精品久久久久| 亚洲一二三四在线| 成人网在线免费视频| 91在线porny国产在线看| 91首页免费视频| 久久久国产精品不卡| 国产精品成人一区二区艾草| 久久99国产精品成人| 成人免费黄色在线| 欧美少妇bbb| 久久精品亚洲麻豆av一区二区 |