Class: Naiso::SplitPointDetector
- Inherits:
-
Object
- Object
- Naiso::SplitPointDetector
- Defined in:
- lib/naiso/split_point_detector.rb
Overview
분할점 감지기
Instance Method Summary collapse
-
#find_background_transitions(variance_threshold: 5.0, min_uniform_height: 20, color_diff_threshold: 15.0) ⇒ Object
배경색 전환 지점 감지.
-
#find_best_split_in_range(start_pos, end_pos, margin: 50) ⇒ Object
주어진 범위 내에서 복잡도가 가장 낮은 분할점 찾기.
-
#find_divider_lines(line_variance_threshold: 3.0, margin_check: 30, margin_variance_threshold: 5.0) ⇒ Object
가로 구분선 감지.
-
#find_uniform_regions ⇒ Object
연속된 단색 영역 찾기.
-
#initialize(analyzer, config) ⇒ SplitPointDetector
constructor
A new instance of SplitPointDetector.
Constructor Details
#initialize(analyzer, config) ⇒ SplitPointDetector
Returns a new instance of SplitPointDetector.
8 9 10 11 |
# File 'lib/naiso/split_point_detector.rb', line 8 def initialize(analyzer, config) @analyzer = analyzer @config = config end |
Instance Method Details
#find_background_transitions(variance_threshold: 5.0, min_uniform_height: 20, color_diff_threshold: 15.0) ⇒ Object
배경색 전환 지점 감지
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 |
# File 'lib/naiso/split_point_detector.rb', line 83 def find_background_transitions( variance_threshold: 5.0, min_uniform_height: 20, color_diff_threshold: 15.0 ) img_array = @analyzer.img_array variance = @analyzer.variance height = @analyzer.height transitions = [] (min_uniform_height...(height - min_uniform_height)).each do |y| # 위아래가 모두 단색인지 확인 above_uniform = variance[(y - min_uniform_height)...y].to_a.all? { |v| v < variance_threshold } below_uniform = variance[y...(y + min_uniform_height)].to_a.all? { |v| v < variance_threshold } next unless above_uniform && below_uniform above_region = img_array[(y - min_uniform_height)...y, true, true] below_region = img_array[y...(y + min_uniform_height), true, true] above_color = calculate_mean_color(above_region) below_color = calculate_mean_color(below_region) # RGB 유클리드 거리 color_diff = Math.sqrt( above_color.zip(below_color).map { |a, b| (a - b) ** 2 }.sum ) transitions << y if color_diff > color_diff_threshold end merge_nearby_points(transitions) end |
#find_best_split_in_range(start_pos, end_pos, margin: 50) ⇒ Object
주어진 범위 내에서 복잡도가 가장 낮은 분할점 찾기
119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/naiso/split_point_detector.rb', line 119 def find_best_split_in_range(start_pos, end_pos, margin: 50) search_start = start_pos + margin search_end = end_pos - margin return (start_pos + end_pos) / 2 if search_start >= search_end window_size = 20 complexity = @analyzer.complexity region = complexity[search_start...search_end] return search_start + region.min_index if region.size < window_size # 이동 평균으로 smoothing smoothed = [] (0...(region.size - window_size)).each do |i| smoothed << region[i...(i + window_size)].mean end best_idx = smoothed.each_with_index.min_by { |v, _| v }[1] + window_size / 2 search_start + best_idx end |
#find_divider_lines(line_variance_threshold: 3.0, margin_check: 30, margin_variance_threshold: 5.0) ⇒ Object
가로 구분선 감지
48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/naiso/split_point_detector.rb', line 48 def find_divider_lines( line_variance_threshold: 3.0, margin_check: 30, margin_variance_threshold: 5.0 ) img_array = @analyzer.img_array variance = @analyzer.variance height = @analyzer.height dividers = [] (margin_check...(height - margin_check)).each do |y| next if variance[y] > line_variance_threshold margin_above = img_array[(y - margin_check)...y, true, true] margin_below = img_array[(y + 1)...(y + 1 + margin_check), true, true] above_variance = calculate_region_variance(margin_above) below_variance = calculate_region_variance(margin_below) next if above_variance > margin_variance_threshold next if below_variance > margin_variance_threshold above_mean = margin_above.cast_to(Numo::DFloat).mean below_mean = margin_below.cast_to(Numo::DFloat).mean line_mean = img_array[y, true, true].cast_to(Numo::DFloat).mean color_diff = (line_mean - (above_mean + below_mean) / 2.0).abs dividers << y if color_diff > 10 end merge_nearby_points(dividers) end |
#find_uniform_regions ⇒ Object
연속된 단색 영역 찾기
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/naiso/split_point_detector.rb', line 14 def find_uniform_regions variance = @analyzer.variance threshold = @config.variance_threshold regions = [] in_region = false region_start = 0 @analyzer.height.times do |i| uniform = variance[i] < threshold if uniform && !in_region in_region = true region_start = i elsif !uniform && in_region in_region = false if i - region_start >= @config.min_gap_height regions << [region_start, i] end end end # 마지막까지 단색이면 if in_region region_end = @analyzer.height if region_end - region_start >= @config.min_gap_height regions << [region_start, region_end] end end regions end |