最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

python中opencv實現(xiàn)文字分割的實踐

 更新時間:2021年06月04日 09:03:49   作者:告白少年  
圖片文字分割的時候,常用的方法有兩種。一種是投影法,還有一種是用OpenCV的輪廓檢測,本文詳細的介紹了這兩種方法的使用,感興趣的可以了解一下

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

投影法

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

算法步驟:

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

橫板文字-小票文字分割

#小票水平分割
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)
# 創(chuàng)建圖像顯示水平投影分割圖像結果
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 = []
# 根據(jù)水平投影分割識別行
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("分行區(qū)域,每行數(shù)據(jù)起始位置Y:", text_rect_x)
# 每行數(shù)據(jù)分段
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)
    # 創(chuàng)建圖像顯示水平投影分割圖像結果
    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)
    # 根據(jù)垂直投影分割識別行
    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
# 在原圖上繪制截圖矩形區(qū)域
print("截取矩形區(qū)域(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.原始圖像進行二值化

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

原始圖像:

在這里插入圖片描述

二值化后的圖像:

在這里插入圖片描述

2.圖像膨脹

投影之前進行圖像灰度學調整做膨脹操作,選取適當?shù)暮?,對圖像進行膨脹處理。

在這里插入圖片描述

3.垂直投影

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

垂直投影結果:

在這里插入圖片描述

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

4.水平投影

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

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)
#創(chuàng)建圖像顯示垂直投影分割圖像結果
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 = []


# 根據(jù)垂直投影分割識別列
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("分列區(qū)域,每列數(shù)據(jù)起始位置Y:", text_rect_y)
# 每列數(shù)據(jù)分段
# 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)
    # 創(chuàng)建圖像顯示水平投影分割圖像結果
    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)
    # 根據(jù)水平投影分割識別行
    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
# 在原圖上繪制截圖矩形區(qū)域
print("截取矩形區(qū)域(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()

分割結果如下:

在這里插入圖片描述

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

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

相關文章

  • python中常用的九個語法技巧

    python中常用的九個語法技巧

    大家好,本篇文章主要講的是python中常用的九個語法技巧,感興趣的同學趕快來看一看吧,對你有幫助的話記得收藏一下
    2022-01-01
  • python文件寫入實例分析

    python文件寫入實例分析

    這篇文章主要介紹了python文件寫入的用法,實例分析了Python文件寫入的使用技巧,非常具有實用價值,需要的朋友可以參考下
    2015-04-04
  • Matlab中關于argmax、argmin函數(shù)的使用解讀

    Matlab中關于argmax、argmin函數(shù)的使用解讀

    這篇文章主要介紹了Matlab中關于argmax、argmin函數(shù)的使用解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-12-12
  • 利用Python實現(xiàn)劉謙春晚魔術

    利用Python實現(xiàn)劉謙春晚魔術

    劉謙在2024年春晚上的撕牌魔術的數(shù)學原理非常簡單,可以用Python完美復現(xiàn),文中通過代碼示例給大家介紹的非常詳細,感興趣的同學可以自己動手嘗試一下
    2024-02-02
  • 淺談Python2、Python3相對路徑、絕對路徑導入方法

    淺談Python2、Python3相對路徑、絕對路徑導入方法

    今天小編就為大家分享一篇淺談Python2、Python3相對路徑、絕對路徑導入方法,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-06-06
  • python PyTorch預訓練示例

    python PyTorch預訓練示例

    這篇文章主要介紹了python PyTorch預訓練示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2018-02-02
  • Python pymysql操作MySQL詳細

    Python pymysql操作MySQL詳細

    pymysql是Python3.x中操作MySQL數(shù)據(jù)庫的模塊,其兼容于MySQLdb,使用方法也與MySQLdb幾乎相同,但是性能不如MySQLdb,但是由于其安裝使用方便、對中文兼容性也更好等優(yōu)點,被廣泛使用??梢允褂胮ip install pymysql進行安裝。
    2021-09-09
  • python DataFrame轉dict字典過程詳解

    python DataFrame轉dict字典過程詳解

    這篇文章主要介紹了python DataFrame轉dict字典過程詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友可以參考下
    2019-12-12
  • 在Python中用GDAL實現(xiàn)矢量對柵格的切割實例

    在Python中用GDAL實現(xiàn)矢量對柵格的切割實例

    這篇文章主要介紹了在Python中用GDAL實現(xiàn)矢量對柵格的切割實例,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-03-03
  • Python使用defaultdict讀取文件各列的方法

    Python使用defaultdict讀取文件各列的方法

    這篇文章主要介紹了Python使用defaultdict讀取文件各列的方法,涉及Python針對文件相關讀取、遍歷操作技巧,需要的朋友可以參考下
    2017-05-05

最新評論

大同县| 邯郸市| 都江堰市| 论坛| 怀柔区| 仁布县| 河北省| 子洲县| 新丰县| 凤城市| 桃园县| 大姚县| 赣州市| 克拉玛依市| 贵定县| 云霄县| 麟游县| 五原县| 泸州市| 特克斯县| 崇阳县| 新乡市| 佛坪县| 盘锦市| 鹤峰县| 祥云县| 河北区| 金华市| 汤阴县| 兴山县| 合山市| 合川市| 定结县| 黄陵县| 新平| 会昌县| 宣城市| 泸溪县| 湖南省| 方城县| 岑巩县|