Class: Naiso::TextDetector

Inherits:
Object
  • Object
show all
Defined in:
lib/naiso/text_detector.rb

Overview

텍스트 검출기

Constant Summary collapse

MIN_TEXT_LENGTH =

최소 텍스트 길이 (공백 제외)

3
MIN_CONFIDENCE =

최소 신뢰도 (0-100, 이 값 미만은 무시)

60.0
MIN_WORD_SIZE =

최소 단어 크기 (픽셀, 이 값 미만은 노이즈로 간주)

10

Instance Method Summary collapse

Constructor Details

#initialize(languages: %w[kor eng],, min_confidence: MIN_CONFIDENCE, min_word_size: MIN_WORD_SIZE) ⇒ TextDetector

Returns a new instance of TextDetector.



17
18
19
20
21
# File 'lib/naiso/text_detector.rb', line 17

def initialize(languages: %w[kor eng], min_confidence: MIN_CONFIDENCE, min_word_size: MIN_WORD_SIZE)
  @languages = languages.join('+')
  @min_confidence = min_confidence
  @min_word_size = min_word_size
end

Instance Method Details

#analyze_images(image_paths, verbose: true, json_path: nil) ⇒ Array<Hash>

여러 이미지에서 텍스트 분석 (크기 정보 포함)

Parameters:

  • image_paths (Array<String>)

    이미지 파일 경로 배열

  • verbose (Boolean) (defaults to: true)

    상세 출력 여부

  • json_path (String, nil) (defaults to: nil)

    JSON 저장 경로 (nil이면 저장 안함)

Returns:

  • (Array<Hash>)

    분석 결과 배열



81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
# File 'lib/naiso/text_detector.rb', line 81

def analyze_images(image_paths, verbose: true, json_path: nil)
  puts "\n텍스트 검출 중..." if verbose

  results = []

  image_paths.each_with_index do |path, i|
    result = detect_with_size(path)
    filename = File.basename(path)

    analysis = {
      filename: filename,
      path: path,
      has_text: result[:has_text],
      text_length: result[:text_length],
      text: result[:text],
      stats: result[:stats],
      words: result[:words]
    }
    results << analysis

    if verbose
      if result[:has_text] && result[:stats]
        stats = result[:stats]
        puts format('  %2d. %-30s 텍스트 있음 (%d자, %d단어) | 높이: %d~%dpx (평균 %.1fpx)',
                    i + 1, filename, result[:text_length], stats[:word_count],
                    stats[:min_height], stats[:max_height], stats[:avg_height])
      else
        puts format('  %2d. %-30s 텍스트 없음', i + 1, filename)
      end
    end
  end

  # JSON 저장
  if json_path
    save_json(results, json_path)
    puts "\nJSON 저장: #{json_path}" if verbose
  end

  # 텍스트 없는 이미지 요약
  no_text_images = results.reject { |r| r[:has_text] }
  if verbose
    puts "\n텍스트 없는 이미지: #{no_text_images.size}"
    no_text_images.each do |r|
      puts "  - #{r[:filename]}"
    end
  end

  results
end

#detect(image_path) ⇒ Hash

이미지에 텍스트가 있는지 검사 원본과 반전 이미지 모두에서 OCR 시도 (흰색 텍스트 대응)

Parameters:

  • image_path (String)

    이미지 파일 경로

Returns:

  • (Hash)

    { has_text: Boolean, text: String, text_length: Integer }



27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
# File 'lib/naiso/text_detector.rb', line 27

def detect(image_path)
  # 원본 이미지에서 OCR
  original_result = ocr_image(image_path)

  # 원본에서 텍스트를 찾았으면 반환
  return original_result if original_result[:has_text]

  # 반전 이미지에서 OCR 시도 (흰색 텍스트 + 어두운 배경 대응)
  inverted_result = ocr_inverted_image(image_path)

  # 더 많은 텍스트를 찾은 결과 반환
  if inverted_result[:text_length] > original_result[:text_length]
    inverted_result
  else
    original_result
  end
rescue StandardError => e
  {
    has_text: false,
    text: '',
    text_length: 0,
    error: e.message
  }
end

#detect_with_size(image_path) ⇒ Hash

텍스트 크기 정보를 포함한 상세 검출

Parameters:

  • image_path (String)

    이미지 파일 경로

Returns:

  • (Hash)

    { has_text:, text:, text_length:, words: [x:, y:, width:, height:, conf:], stats: max_height:, avg_height: }



55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/naiso/text_detector.rb', line 55

def detect_with_size(image_path)
  result = detect_tsv(image_path)

  # 원본에서 못 찾으면 반전 이미지 시도
  unless result[:has_text]
    inverted_result = detect_tsv_inverted(image_path)
    result = inverted_result if inverted_result[:text_length] > result[:text_length]
  end

  result
rescue StandardError => e
  {
    has_text: false,
    text: '',
    text_length: 0,
    words: [],
    stats: nil,
    error: e.message
  }
end

#find_images_without_text(image_paths, verbose: true) ⇒ Array<String>

여러 이미지에서 텍스트 없는 이미지 찾기 (하위 호환성)

Parameters:

  • image_paths (Array<String>)

    이미지 파일 경로 배열

  • verbose (Boolean) (defaults to: true)

    상세 출력 여부

Returns:

  • (Array<String>)

    텍스트가 없는 이미지 경로 배열



135
136
137
138
# File 'lib/naiso/text_detector.rb', line 135

def find_images_without_text(image_paths, verbose: true)
  results = analyze_images(image_paths, verbose: verbose)
  results.reject { |r| r[:has_text] }.map { |r| r[:path] }
end