Spring 引导应用程序中的 Tesseract 为日语提供了无意义的结果
Tesseract in Spring Boot Application gives nonsense results for Japanese
我正在编写一个 Spring 引导应用程序,它使用 Bytedeco's Java Wrapper for Tesseract OCR 来解析日语文本。当 运行 在 Spring Boot 之外时,我设法让 Tesseract 正常工作,但是当我在 Spring Boot 应用程序中使用它时,它给了我无意义的结果。
例如,给定下图:
如果我运行下面的函数,结果是合理的:
fun main() {
val api = tesseract.TessBaseAPI()
api.Init("src/main/resources/tessdata", "jpn_vert")
api.SetPageSegMode(tesseract.PSM_SINGLE_BLOCK_VERT_TEXT)
val pixImage = lept.pixRead("src/main/resources/image.png")
api.SetImage(pixImage)
val result = api.GetUTF8Text()
System.out.println("Parsed text: " + result?.string)
}
打印:
Parsed text:
坊っちゃん
夏目 滞 石
如果我 运行 它来自 Spring 引导 Web 套接字,但是,结果不是:
@SpringBootApplication
open class BootApplication
fun main(args: Array<String>) {
runApplication<BootApplication>(*args)
}
@Configuration
@EnableWebSocket
open class WebSocketConfiguration: WebSocketConfigurer {
@Bean
open fun createWebSocketContainer(): ServletServerContainerFactoryBean {
val container = ServletServerContainerFactoryBean()
container.maxBinaryMessageBufferSize = 1024000
return container
}
override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
registry.addHandler(Endpoint(), "/parse").setAllowedOrigins("*")
}
}
class Endpoint: AbstractWebSocketHandler() {
@Throws(IOException::class)
override fun handleBinaryMessage(session: WebSocketSession?, message: BinaryMessage?) {
// Same code as above:
val api = tesseract.TessBaseAPI()
api.Init("src/main/resources/tessdata", "jpn_vert")
api.SetPageSegMode(tesseract.PSM_SINGLE_BLOCK_VERT_TEXT)
val pixImage = lept.pixRead("src/main/resources/image.png")
api.SetImage(pixImage)
val result = api.GetUTF8Text()
System.out.println("Parsed text:\n" + result?.string)
}
}
调用 handleBinaryMessage
时打印以下内容:
Parsed text:
蝮翫▲縺。繧?繧?
螟冗岼 貊? 遏ウ
我 运行 对一些英文文本进行了快速测试并且效果很好,所以我认为这个问题是 language-specific。
我正在 运行使用启动 Apache Tomcat 服务的 Spring Boot Gradle 插件中的 bootRun
任务来启动 Boot 应用程序。我的第一个想法是,这与以下事实有关:Tesseract 包装器是一个 JNI 库,并且它在 运行ning (Tomcat) 中的环境不一样。如果是这样,是否需要进行一些额外的配置才能让 Tesseract 与 Spring Boot 和 Tomcat 一起工作?
供参考,我的build.gradle
如下:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.10'
id("org.springframework.boot") version "2.1.0.RELEASE"
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation group: "org.bytedeco.javacpp-presets", name: "tesseract", version: "4.0.0-rc2-1.4.3"
implementation group: "org.bytedeco.javacpp-presets", name: "tesseract", version: "4.0.0-rc2-1.4.3", classifier: "windows-x86_64"
implementation group: "org.bytedeco.javacpp-presets", name: "leptonica", version: "1.76.0-1.4.3", classifier: "windows-x86_64"
implementation group: "org.springframework.boot", name: "spring-boot", version: "2.1.0.RELEASE"
implementation group: "org.springframework.boot", name: "spring-boot-starter-web", version: "2.1.0.RELEASE"
implementation group: "org.springframework", name: "spring-websocket", version: "5.1.2.RELEASE"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
编辑
看起来是编码问题。 Java 的 file.encoding
系统 属性 在 运行 从引导外部设置为 UTF-8
,但在引导时设置为 windows-31j
。将 result?.string
切换为 result?.getString("UTF-8")
修复了它。
我将把这归因于 Bytedeco 的 Tesseract 包装器的错误。我用 tess4j 做了等效测试,没有问题:
val imageFile = File("src/main/resources/image.png")
val tess = Tesseract()
tess.setPageSegMode(PSM_SINGLE_BLOCK_VERT_TEXT)
tess.setLanguage("jpn_vert")
System.out.println("Parsed text:\n" + tess.doOCR(imageFile))
给我:
坊っちゃん
夏目 滞 石
符合预期。
我已经提交了 ticket on their github,所以希望不久之后就能解决这个问题。
我正在编写一个 Spring 引导应用程序,它使用 Bytedeco's Java Wrapper for Tesseract OCR 来解析日语文本。当 运行 在 Spring Boot 之外时,我设法让 Tesseract 正常工作,但是当我在 Spring Boot 应用程序中使用它时,它给了我无意义的结果。
例如,给定下图:
如果我运行下面的函数,结果是合理的:
fun main() {
val api = tesseract.TessBaseAPI()
api.Init("src/main/resources/tessdata", "jpn_vert")
api.SetPageSegMode(tesseract.PSM_SINGLE_BLOCK_VERT_TEXT)
val pixImage = lept.pixRead("src/main/resources/image.png")
api.SetImage(pixImage)
val result = api.GetUTF8Text()
System.out.println("Parsed text: " + result?.string)
}
打印:
Parsed text:
坊っちゃん
夏目 滞 石
如果我 运行 它来自 Spring 引导 Web 套接字,但是,结果不是:
@SpringBootApplication
open class BootApplication
fun main(args: Array<String>) {
runApplication<BootApplication>(*args)
}
@Configuration
@EnableWebSocket
open class WebSocketConfiguration: WebSocketConfigurer {
@Bean
open fun createWebSocketContainer(): ServletServerContainerFactoryBean {
val container = ServletServerContainerFactoryBean()
container.maxBinaryMessageBufferSize = 1024000
return container
}
override fun registerWebSocketHandlers(registry: WebSocketHandlerRegistry) {
registry.addHandler(Endpoint(), "/parse").setAllowedOrigins("*")
}
}
class Endpoint: AbstractWebSocketHandler() {
@Throws(IOException::class)
override fun handleBinaryMessage(session: WebSocketSession?, message: BinaryMessage?) {
// Same code as above:
val api = tesseract.TessBaseAPI()
api.Init("src/main/resources/tessdata", "jpn_vert")
api.SetPageSegMode(tesseract.PSM_SINGLE_BLOCK_VERT_TEXT)
val pixImage = lept.pixRead("src/main/resources/image.png")
api.SetImage(pixImage)
val result = api.GetUTF8Text()
System.out.println("Parsed text:\n" + result?.string)
}
}
调用 handleBinaryMessage
时打印以下内容:
Parsed text:
蝮翫▲縺。繧?繧?
螟冗岼 貊? 遏ウ
我 运行 对一些英文文本进行了快速测试并且效果很好,所以我认为这个问题是 language-specific。
我正在 运行使用启动 Apache Tomcat 服务的 Spring Boot Gradle 插件中的 bootRun
任务来启动 Boot 应用程序。我的第一个想法是,这与以下事实有关:Tesseract 包装器是一个 JNI 库,并且它在 运行ning (Tomcat) 中的环境不一样。如果是这样,是否需要进行一些额外的配置才能让 Tesseract 与 Spring Boot 和 Tomcat 一起工作?
供参考,我的build.gradle
如下:
plugins {
id 'org.jetbrains.kotlin.jvm' version '1.3.10'
id("org.springframework.boot") version "2.1.0.RELEASE"
}
repositories {
mavenCentral()
}
dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8"
implementation group: "org.bytedeco.javacpp-presets", name: "tesseract", version: "4.0.0-rc2-1.4.3"
implementation group: "org.bytedeco.javacpp-presets", name: "tesseract", version: "4.0.0-rc2-1.4.3", classifier: "windows-x86_64"
implementation group: "org.bytedeco.javacpp-presets", name: "leptonica", version: "1.76.0-1.4.3", classifier: "windows-x86_64"
implementation group: "org.springframework.boot", name: "spring-boot", version: "2.1.0.RELEASE"
implementation group: "org.springframework.boot", name: "spring-boot-starter-web", version: "2.1.0.RELEASE"
implementation group: "org.springframework", name: "spring-websocket", version: "5.1.2.RELEASE"
}
compileKotlin {
kotlinOptions.jvmTarget = "1.8"
}
编辑
看起来是编码问题。 Java 的 file.encoding
系统 属性 在 运行 从引导外部设置为 UTF-8
,但在引导时设置为 windows-31j
。将 result?.string
切换为 result?.getString("UTF-8")
修复了它。
我将把这归因于 Bytedeco 的 Tesseract 包装器的错误。我用 tess4j 做了等效测试,没有问题:
val imageFile = File("src/main/resources/image.png")
val tess = Tesseract()
tess.setPageSegMode(PSM_SINGLE_BLOCK_VERT_TEXT)
tess.setLanguage("jpn_vert")
System.out.println("Parsed text:\n" + tess.doOCR(imageFile))
给我:
坊っちゃん
夏目 滞 石
符合预期。
我已经提交了 ticket on their github,所以希望不久之后就能解决这个问题。