图片文字提取之路-01预处理
生活随笔
收集整理的這篇文章主要介紹了
图片文字提取之路-01预处理
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
最近突然對機器學習產生了興趣, 而機器視覺是非常重要的一塊。那么,首先來走出第一步,從圖片中提取文字信息
圖片文字提取是模式識別中一個細小的分支,偶爾看見了一篇叫做《基于高階神經網絡的文字識別》論文,讓我有了一個大概的路線,讓我們開始吧:
一.圖片預處理階段
以下的代碼均采用golang
main方法實現:
package mainimport("fmt""os""image/png""image""image/color""sort""strconv" ) //定義最大處理圖片像素 const MAX_LENGTH = 1000 //定義圖片的長度和高度 var dx,dy int //定義圖片灰度的二維數組 var graySet [1000][1000]int //定義二值化后圖片圖片的情況,0代表背景,1代表目標 var binarizationSet [1000][1000]int var binarizationSetCopy [1000][1000]intfunc main() {//1.圖片灰度化newPath := Gray("a.png")//2.對圖片二值化newPath = Binarization(newPath)//3.對圖片進行長線剔除//4.平滑中值去噪//newPath = Denoising(newPath)//5.圖片細化Refinement(newPath)fmt.Println("圖片寬:"+strconv.Itoa(dx)+",高:"+strconv.Itoa(dy)); }
1.圖片灰度化
/*** 加權平均法 * 根據重要性及其它指標,將三個分量以不同的權值進行加權平均。* 由于人眼對綠色的敏感最高,對藍色敏感最低,* 因此,按下式對RGB三分量進行加權平均能得到較合理的灰度圖像。 * f(i,j)=0.30R(i,j)+0.59G(i,j)+0.11B(i,j))*/ func Gray(path string) string {file, err := os.Open(path)if err != nil {fmt.Println(err)}defer file.Close()pngFile, _ := png.Decode( file )bounds := pngFile.Bounds()dx = bounds.Max.Xdy = bounds.Max.Ygray := image.NewGray(image.Rect(0, 0, dx, dy))var r32,g32,b32 uint32 var r8,g8,b8 float32var newGray bytefor x := 0; x < dx; x++ {for y := 0; y < dy; y++ {//計算該點的灰度r32, g32, b32, _ = pngFile.At(x, y).RGBA()r8,g8,b8 = float32(r32>>8), float32(g32>>8), float32(b32>>8)newGray = uint8( 0.299 * r8 + 0.587 * g8 + 0.114 * b8 )graySet[x][y] = int(newGray)gray.Set(x, y, color.Gray{newGray})}}newPath := "b.png"newFile, _ := os.Create(newPath)png.Encode(newFile, gray)return newPath }處理結果:
2.圖片二值化
//圖片二值化,閥值固定為180,固定<span style="font-family: Arial, Helvetica, sans-serif;">閥值,可以根據具體實驗結果設置</span>func Binarization(path string) string {newPath := "c.png"file, err := os.Open(path)if err != nil {fmt.Println(err)}defer file.Close()pngFile, _ := png.Decode( file )gray := image.NewGray(image.Rect(0, 0, dx, dy))var r32,g32,b32 uint32 var r,g,b intfor x := 0; x < dx; x++ {for y := 0; y < dy; y++ {//計算該點的灰度r32, g32, b32, _ = pngFile.At(x, y).RGBA()r,g,b = int(r32>>8), int(g32>>8), int(b32>>8)if ( (r+g+b)/3 > 180 ) {binarizationSet[x][y] = 0gray.Set(x, y, color.Gray{uint8(255)})} else {binarizationSet[x][y] = 1gray.Set(x, y, color.Gray{uint8(0)})}}}newFile, _ := os.Create(newPath)png.Encode(newFile, gray)return newPath }處理結果:
3.平滑中值去噪
//平滑中值去噪,3*3像素方陣中找灰度中值 func Denoising(path string) string {var middleGray uint8newPath := "d.png"gray := image.NewGray(image.Rect(0, 0, dx, dy))for x := 0; x < dx; x++ {for y := 0; y < dy; y++ {middleGray = getMiddleGray( x, y )gray.Set(x, y, color.Gray{middleGray})}}newFile, _ := os.Create(newPath)png.Encode(newFile, gray)return newPath }//獲取該點的灰度中值,如果數量為偶數,則去中間兩個值得平均,否者直接去的中值 func getMiddleGray( x int, y int) uint8 {grayWindow := []int{0,0,0,0,0,0,0,0,0}if(x!=0 && y!=0 && x!=dx-1 && y!=dy-1) {grayWindow[0] = graySet[x-1][y-1]grayWindow[1] = graySet[x][y-1]grayWindow[2] = graySet[x+1][y-1]grayWindow[3] = graySet[x-1][y]grayWindow[4] = graySet[x][y]grayWindow[5] = graySet[x+1][y-1]grayWindow[6] = graySet[x-1][y+1]grayWindow[7] = graySet[x][y+1]grayWindow[8] = graySet[x+1][y-1]sort.Ints(grayWindow)return uint8(grayWindow[4])} else {return uint8(graySet[x][y])} }處理結果:
4.圖片細化
//Hilditch算法, 見http://www.cnblogs.com/xiaotie/archive/2010/08/12/1797760.html //(I):p 為1,即p不是背景; //(2):x1,x3,x5,x7不全部為1(否則把p標記刪除,圖像空心了); //(3):x1~x8 中,至少有2個為1(若只有1個為1,則是線段的端點。若沒有為1的,則為孤立點); //(4):p的8連通聯結數為1; /// 計算八聯結的聯結數,計算公式為: /// (p6 - p6*p7*p0) + sigma(pk - pk*p(k+1)*p(k+2)), k = {0,2,4) //(5)假設x3已經標記刪除,那么當x3為0時,p的8聯通聯結數為1; //(6)假設x5已經標記刪除,那么當x5為0時,p的8聯通聯結數為1。 // x4 x3 x2 // x5 p x1 // x6 x7 x8 // // p3 p2 p1 // p4 p p0 // p5 p6 p7 func Hilditch(x int, y int) int {neighor := []int{0,0,0,0,0,0,0,0} if(x!=0 && y!=0 && x!=dx-1 && y!=dy-1) {neighor[0] = binarizationSet[x+1][y] //x1neighor[1] = binarizationSet[x+1][y-1] //x2neighor[2] = binarizationSet[x][y-1] //x3neighor[3] = binarizationSet[x-1][y-1] //x4neighor[4] = binarizationSet[x-1][y] //x5neighor[5] = binarizationSet[x-1][y+1] //x6neighor[6] = binarizationSet[x][y+1] //x7neighor[7] = binarizationSet[x+1][y+1] //x8if( binarizationSetCopy[x][y-1] == 1 && binarizationSet[x][y-1] == 0 ) {neighor[2] = 1 }if( binarizationSetCopy[x-1][y] == 1 && binarizationSet[x-1][y] == 0 ) {neighor[4] = 1 }number := 0for i:= 0 ; i<8 ; i++ {if neighor[i] == 1 {number ++}}//獲取聯通連接數unicomConnection := unicomConnectionCalc( neighor )//條件2if neighor[0]*neighor[2]*neighor[4]*neighor[6] == 0 { //條件3 if number >= 2 {//條件4if unicomConnection == 1 {//條件5if( binarizationSetCopy[x][y-1] == 1 && binarizationSet[x][y-1] == 0 ) {neighor[2] = 0unicomConnection := unicomConnectionCalc( neighor )if( unicomConnection != 1 ) { //條件不滿足return 1}neighor[2] = 1}//條件6if( binarizationSetCopy[x-1][y] == 1 && binarizationSet[x-1][y] == 0 ) {neighor[4] = 0unicomConnection := unicomConnectionCalc( neighor )if( unicomConnection != 1 ) { //條件不滿足return 1}}return 0}}}}return 1 }//Hilditch算法,用于獲取聯通數 func unicomConnectionCalc( neighor []int ) int {unicomConnection := neighor[6]-neighor[6]*neighor[7]*neighor[0]unicomConnection = unicomConnection + neighor[0]-neighor[0]*neighor[1]*neighor[2]unicomConnection = unicomConnection + neighor[2]-neighor[2]*neighor[3]*neighor[4]unicomConnection = unicomConnection + neighor[4]-neighor[4]*neighor[5]*neighor[6]return unicomConnection }處理結果
如果有不正確的地方,還請指正,謝謝!
未完待續...
總結
以上是生活随笔為你收集整理的图片文字提取之路-01预处理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: laravel 队列学习
- 下一篇: [每日编程]求 largest Numb