>백엔드 개발 >Golang >Golang의 이미지 분할 및 콘텐츠 인식 방법

Golang의 이미지 분할 및 콘텐츠 인식 방법

WBOY
WBOY원래의
2023-08-19 14:03:561893검색

Golang의 이미지 분할 및 콘텐츠 인식 방법

Golang의 이미지 분할 및 콘텐츠 인식 방법

인공지능과 컴퓨터 비전 기술의 발전으로 이미지 분할과 콘텐츠 인식이 다양한 분야에서 점점 더 중요한 역할을 하고 있습니다. 이 기사에서는 Golang을 사용하여 이미지 분할 및 콘텐츠 인식을 달성하는 방법을 소개하고 코드 예제가 제공됩니다.

시작하기 전에 몇 가지 필수 Go 패키지를 설치해야 합니다. 먼저 텍스트 인식을 위한 Golang 라이브러리인 "github.com/otiai10/gosseract/v2"를 설치해야 합니다. 둘째, 행렬 연산을 위한 Golang 라이브러리인 "gonum.org/v1/gonum/mat"도 설치해야 합니다. 다음 명령을 사용하여 설치할 수 있습니다.

go get github.com/otiai10/gosseract/v2
go get -u gonum.org/v1/gonum/...

다음으로, 다음 단계를 통해 이미지 분할 및 콘텐츠 인식을 구현하겠습니다.

1단계: 이미지를 읽고 그레이스케일로 처리

먼저 파일에서 이미지를 읽어 그레이스케일 이미지로 변환해야 합니다. 코드 예시는 다음과 같습니다.

package main

import (
    "fmt"
    "image"
    "image/color"
    "image/jpeg"
    "os"
)

func main() {
    file, err := os.Open("image.jpg")
    if err != nil {
        fmt.Println("图片读取失败:", err)
        return
    }
    defer file.Close()

    img, err := jpeg.Decode(file)
    if err != nil {
        fmt.Println("图片解码失败:", err)
        return
    }

    gray := image.NewGray(img.Bounds())
    for x := gray.Bounds().Min.X; x < gray.Bounds().Max.X; x++ {
        for y := gray.Bounds().Min.Y; y < gray.Bounds().Max.Y; y++ {
            r, g, b, _ := img.At(x, y).RGBA()
            grayColor := color.Gray{(r + g + b) / 3}
            gray.Set(x, y, grayColor)
        }
    }
}

이 코드에서는 먼저 "image.jpg"라는 이미지를 열고 읽습니다. 그런 다음 "jpeg.Decode" 함수를 통해 사진을 이미지 개체로 디코딩합니다. 다음으로, 새로운 회색조 이미지 객체 "gray"를 생성하고 이중 루프를 사용하여 원본 이미지를 회색조로 변환했습니다.

2단계: 이미지 분할

회색조 이미지를 얻은 후 일부 이미지 처리 알고리즘을 사용하여 이미지를 분할할 수 있습니다. 여기서는 임계값 분할을 위해 OTSU 알고리즘을 사용합니다. 코드 예는 다음과 같습니다.

package main

import (
    "fmt"
    "image"
    "image/color"
    "image/jpeg"
    "math"
    "os"
)

func main() {
    // ...

    // 分割图片
    bounds := gray.Bounds()
    threshold := otsu(gray) // OTSU算法获取阈值
    binary := image.NewGray(bounds)
    for x := bounds.Min.X; x < bounds.Max.X; x++ {
        for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
            if gray.GrayAt(x, y).Y > threshold {
                binary.Set(x, y, color.Gray{255})
            } else {
                binary.Set(x, y, color.Gray{0})
            }
        }
    }
}

// OTSU算法计算阈值
func otsu(img *image.Gray) uint32 {
    var hist [256]int
    bounds := img.Bounds()
    for x := bounds.Min.X; x < bounds.Max.X; x++ {
        for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
            hist[img.GrayAt(x, y).Y]++
        }
    }

    total := bounds.Max.X * bounds.Max.Y
    var sum float64
    for i := 0; i < 256; i++ {
        sum += float64(i) * float64(hist[i])
    }
    var sumB float64
    wB := 0
    wF := 0
    var varMax float64
    threshold := 0

    for t := 0; t < 256; t++ {
        wB += hist[t]
        if wB == 0 {
            continue
        }
        wF = total - wB
        if wF == 0 {
            break
        }
        sumB += float64(t) * float64(hist[t])

        mB := sumB / float64(wB)
        mF := (sum - sumB) / float64(wF)

        var between float64 = float64(wB) * float64(wF) * (mB - mF) * (mB - mF)
        if between >= varMax {
            threshold = t
            varMax = between
        }
    }

    return uint32(threshold)
}

이 코드에서는 OTSU 알고리즘의 임계값을 계산하기 위해 "otsu"라는 함수를 정의합니다. 그런 다음 "main" 함수에서 이 함수를 사용하여 임계값을 얻습니다. 다음으로, 새로운 이진 이미지 "binary"를 생성하고 이중 루프를 사용하여 회색조 이미지를 임계값으로 분할합니다.

3단계: 콘텐츠 식별

이미지를 분할한 후 "gosseract" 라이브러리를 사용하여 각 영역의 콘텐츠를 식별할 수 있습니다. 코드 예시는 다음과 같습니다.

package main

import (
    "fmt"
    "image"
    "image/color"
    "image/jpeg"
    "os"
    "strings"

    "github.com/otiai10/gosseract/v2"
)

func main() {
    // ...

    client := gosseract.NewClient()
    defer client.Close()

    texts := make([]string, 0)
    bounds := binary.Bounds()
    for x := bounds.Min.X; x < bounds.Max.X; x++ {
        for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
            if binary.GrayAt(x, y).Y == 255 {
                continue
            }
            sx := x
            sy := y
            ex := x
            ey := y
            for ; ex < bounds.Max.X && binary.GrayAt(ex, y).Y == 0; ex++ {
            }
            for ; ey < bounds.Max.Y && binary.GrayAt(x, ey).Y == 0; ey++ {
            }
            rect := image.Rect(sx, sy, ex, ey)
            subImg := binary.SubImage(rect)

            pix := subImg.Bounds().Max.X * subImg.Bounds().Max.Y
            blackNum := 0
            for i := subImg.Bounds().Min.X; i < subImg.Bounds().Max.X; i++ {
                for j := subImg.Bounds().Min.Y; j < subImg.Bounds().Max.Y; j++ {
                    if subImg.At(i, j) == color.Gray{255} {
                        blackNum++
                    }
                }
            }
            if float64(blackNum)/float64(pix) < 0.1 { // 去除噪音
                continue
            }

            output, _ := client.ImageToText(subImg)
            output = strings.ReplaceAll(output, "
", "")
            output = strings.ReplaceAll(output, " ", "")
            texts = append(texts, output)
        }
    }

    fmt.Println(texts)
}

이 코드에서는 "gosseract" 라이브러리의 "NewClient" 및 "Close" 함수를 사용하여 인식 클라이언트를 생성하고 닫습니다. 그런 다음 이중 루프를 사용하여 분할된 이진 이미지를 반복합니다. 흰색이 아닌 영역의 경우 해당 영역의 좌표 범위를 가져와 하위 이미지로 변환합니다. 다음으로, 노이즈를 제거하기 위해 하위 이미지의 검은색 픽셀 비율을 계산합니다. 마지막으로 "ImageToText" 함수를 통해 하위 이미지를 텍스트로 변환하고 결과를 "texts" 배열에 저장합니다.

위의 단계를 통해 Golang을 사용하여 이미지 분할 및 콘텐츠 인식을 달성하는 방법을 완성했습니다. 다양한 시나리오와 요구 사항에 적응하기 위해 필요에 따라 코드를 수정하고 최적화할 수 있습니다. 이 글이 이미지 분할과 콘텐츠 인식 기술을 이해하고 적용하는데 조금이나마 도움이 되기를 바랍니다.

위 내용은 Golang의 이미지 분할 및 콘텐츠 인식 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.