다음의 코드가 이상하다. 수정할 부분은 수정하여 정리해서 전체 코드를 만들어줘
import easyocr
import fitz  # PyMuPDF
from pyhwpx import Hwp
from PIL import Image, ImageEnhance, ImageFilter
import numpy as np
import cv2
import os

def enhance_image_for_ocr(img):
    """OCR 성능 향상을 위한 고급 이미지 전처리"""
    try:
        # RGB 이미지인지 확인
        if img.mode != 'RGB':
            img = img.convert('RGB')
        
        # 이미지 배열로 변환
        img_array = np.array(img)
        
        # 이미지 크기 확인
        if img_array.size == 0:
            print("⚠️ 빈 이미지가 전달되었습니다. 원본 이미지를 반환합니다.")
            return img
            
        # 그레이스케일 변환
        try:
            gray = cv2.cvtColor(img_array, cv2.COLOR_RGB2GRAY)
        except cv2.error:
            print("⚠️ 이미지 색상 변환 오류. 대체 방법 사용.")
            gray = np.array(img.convert('L'))  # PIL의 그레이스케일 변환 사용
        
        # 이진화 - 적응형 임계값 적용 (안전하게 처리)
        try:
            binary = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, 
                                        cv2.THRESH_BINARY, 11, 2)
        except Exception as e:
            print(f"⚠️ 이진화 오류: {e}. 대체 방법 사용.")
            # 간단한 임계값 이진화로 대체
            _, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
        
        # 노이즈 제거 (안전하게 처리)
        try:
            denoised = cv2.fastNlMeansDenoising(binary, None, 10, 7, 21)
        except Exception as e:
            print(f"⚠️ 노이즈 제거 오류: {e}. 이진화 결과 사용.")
            denoised = binary
        
        # 선명도 향상 (안전하게 처리)
        try:
            kernel = np.array([[-1,-1,-1], [-1,9,-1], [-1,-1,-1]])
            sharpened = cv2.filter2D(denoised, -1, kernel)
        except Exception as e:
            print(f"⚠️ 선명도 향상 오류: {e}. 노이즈 제거 결과 사용.")
            sharpened = denoised
        
        # PIL 이미지로 변환
        enhanced_img = Image.fromarray(sharpened)
        
        # 대비 조정 (안전하게 처리)
        try:
            enhancer = ImageEnhance.Contrast(enhanced_img)
            enhanced_img = enhancer.enhance(2.2)
        except Exception as e:
            print(f"⚠️ 대비 조정 오류: {e}. 선명도 향상 결과 사용.")
        
        return enhanced_img
    
    except Exception as e:
        print(f"⚠️ 이미지 전처리 중 예상치 못한 오류: {e}")
        print("   원본 이미지를 반환합니다.")
        return img

def extract_text_with_format(reader, img, zoom=2):
    """이미지에서 텍스트 및 서식 추출 (개선된 버전)"""
    try:
        # 이미지 유효성 검사
        if isinstance(img, np.ndarray):
            if img.size == 0:
                print("⚠️ 빈 이미지 배열입니다.")
                return []
        else:
            img = np.array(img)  # PIL 이미지를 배열로 변환
        
        # OCR 매개변수 안전 설정
        ocr_params = {
            'detail': 2,
            'paragraph': True,
            'width_ths': 0.7,     # 단어 간격 인식 매개변수 조정
            'height_ths': 0.7,    # 줄 간격 인식 매개변수 조정
            'ycenter_ths': 0.5,   # 중앙 정렬 감지 임계값
            'add_margin': 0.1,    # 여백 추가
        }
        
        # 고급 OCR 설정 시도 (실패 시 기본 설정 사용)
        try:
            ocr_params['decoder'] = 'beamsearch'  # 정확도 향상을 위한 디코더
            ocr_params['beamWidth'] = 5           # 빔 너비 증가로 정확도 향상
            results = reader.readtext(img, **ocr_params)
        except Exception as e:
            print(f"⚠️ 고급 OCR 설정 오류: {e}. 기본 설정으로 진행합니다.")
            # 기본 설정으로 다시 시도
            ocr_params.pop('decoder', None)
            ocr_params.pop('beamWidth', None)
            results = reader.readtext(img, **ocr_params)
        
        # 결과가 없으면 빈 배열 반환
        if not results:
            print("⚠️ OCR 결과가 없습니다.")
            return []
        
        # 텍스트 구조 분석 및 문단 구성
        formatted_results = []
        
        # 모든 텍스트 상자의 평균 높이 계산
        heights = []
        for result in results:
            if len(result) >= 2:  # 최소한 bbox와 text는 있어야 함
                bbox = result[0]
                if len(bbox) >= 3:  # 최소한 3개 이상의 좌표 필요
                    height = abs(bbox[2][1] - bbox[0][1])
                    heights.append(height)
        
        avg_height = sum(heights) / len(heights) if heights else 0
        
        for result in results:
            try:
                # 결과 형식 확인 및 파싱
                if len(result) == 4:
                    bbox, text, prob, extra = result
                elif len(result) == 3:
                    bbox, text, prob = result
                    extra = {}
                elif len(result) == 2:
                    bbox, text = result
                    prob = 0.0
                    extra = {}
                else:
                    print(f"⚠️ 지원되지 않는 OCR 결과 형식: {result}")
                    continue
                
                # 텍스트가 비어 있으면 건너뛰기
                if not text or text.isspace():
                    continue
                
                # 바운딩 박스 형식 확인
                if len(bbox) < 4:
                    print(f"⚠️ 잘못된 바운딩 박스 형식: {bbox}")
                    continue
                
                # 좌표 계산 (points 단위로 변환)
                x1 = int(bbox[0][0] / zoom * 352.778)
                y1 = int(bbox[0][1] / zoom * 352.778)
                x2 = int(bbox[2][0] / zoom * 352.778)
                y2 = int(bbox[2][1] / zoom * 352.778)
                
                width = x2 - x1
                height = y2 - y1
                
                # 텍스트 서식 감지 (글꼴 크기, 굵기, 기울임, 밑줄)
                font_size = 10  # 기본 글꼴 크기
                
                # 글꼴 크기 추정 (높이 기반)
                if avg_height > 0:
                    rel_height = height / avg_height
                    if rel_height > 1.5:
                        font_size = 16  # 큰 텍스트 (제목 등)
                    elif rel_height > 1.2:
                        font_size = 13  # 중간 크기 텍스트
                    elif rel_height < 0.8:
                        font_size = 9   # 작은 텍스트 (각주 등)
                
                # 서식 감지 (향후 ML 모델 활용 가능)
                is_bold = prob > 0.95 and height > avg_height * 1.1  # 확률이 높고 크기가 큰 경우 굵은 글씨로 간주
                is_italic = False  # 기울임 감지 로직 (향후 구현)
                is_underline = False  # 밑줄 감지 로직 (향후 구현)
                
                # 제목 감지
                is_heading = height > avg_height * 1.3 or font_size >= 13
                
                # 결과 구조화
                formatted_result = {
                    'text': text,
                    'bbox': (x1, y1, x2, y2),
                    'width': width,
                    'height': height,
                    'prob': prob,
                    'font_size': font_size,
                    'is_bold': is_bold,
                    'is_italic': is_italic,
                    'is_underline': is_underline,
                    'is_heading': is_heading
                }
                
                formatted_results.append(formatted_result)
                
            except Exception as e:
                print(f"⚠️ OCR 결과 처리 중 오류: {e}")
                continue
        
        return formatted_results
        
    except Exception as e:
        print(f"⚠️ 텍스트 추출 중 예상치 못한 오류: {e}")
        import traceback
        traceback.print_exc()
        return []

def normalize_text_spacing(formatted_results):
    """텍스트 간격과 줄 구분을 조정"""
    # 세로 방향으로 정렬
    formatted_results.sort(key=lambda x: (x['bbox'][1], x['bbox'][0]))
    
    # 줄 그룹화
    lines = []
    current_line = []
    current_y = None
    
    for result in formatted_results:
        if current_y is None or abs(result['bbox'][1] - current_y) <= result['height'] * 0.5:
            current_line.append(result)
            current_y = result['bbox'][1] if current_y is None else current_y
        else:
            # 현재 줄 내 항목을 x좌표로 정렬
            current_line.sort(key=lambda x: x['bbox'][0])
            lines.append(current_line)
            current_line = [result]
            current_y = result['bbox'][1]
    
    if current_line:
        current_line.sort(key=lambda x: x['bbox'][0])
        lines.append(current_line)
    
    # 각 줄의 단어 간격 계산 및 정규화
    normalized_lines = []
    for line in lines:
        normalized_line = []
        prev_end_x = None
        
        for word in line:
            # 올바른 공백 추가
            if prev_end_x is not None:
                space_width = word['bbox'][0] - prev_end_x
                num_spaces = max(1, round(space_width / (word['width'] * 0.3)))
                
                # 간격이 충분히 넓다면 공백 추가
                if space_width > word['width'] * 0.3:
                    word['prefix_spaces'] = ' ' * num_spaces
                else:
                    word['prefix_spaces'] = ''
            else:
                word['prefix_spaces'] = ''
            
            normalized_line.append(word)
            prev_end_x = word['bbox'][2]
        
        normalized_lines.append(normalized_line)
    
    return normalized_lines

def apply_text_to_hwp(hwp, normalized_lines):
    """정규화된 텍스트를 한글 문서에 적용"""
    for line_idx, line in enumerate(normalized_lines):
        line_text = ""
        
        for word in line:
            # 글자 서식 설정
            char_shape = {
                "Size": word['font_size'],
                "Bold": word['is_bold'],
                "Italic": word['is_italic'],
                "Underline": word['is_underline']
            }
            
            # 제목으로 감지되었다면 추가 서식 적용
            if word['is_heading']:
                char_shape["Size"] = int(word['font_size'] * 1.2)  # 크기 키우기
                char_shape["Bold"] = True  # 제목은 볼드 처리
            
            # 서식 적용
            hwp.SetCharShape(char_shape)
            
            # 단어 앞에 적절한 공백 추가
            line_text += word['prefix_spaces'] + word['text']
        
        # 줄 추가
        if line_text.strip():
            hwp.insert_text(line_text.strip())
            
            # 다음 줄로 이동 (마지막 줄이 아닌 경우)
            if line_idx < len(normalized_lines) - 1:
                # 다음 줄과의 간격 계산
                current_y_end = max(word['bbox'][3] for word in line)
                next_y_start = min(word['bbox'][1] for word in normalized_lines[line_idx + 1])
                
                # 줄 간격이 충분히 넓으면 빈 줄 추가
                line_spacing = next_y_start - current_y_end
                avg_height = sum(word['height'] for word in line) / len(line)
                
                if line_spacing > avg_height * 1.5:
                    hwp.insert_text("\n\n")  # 빈 줄 추가
                else:
                    hwp.insert_text("\n")  # 일반 줄바꿈
            else:
                hwp.insert_text("\n")

def detect_tables_and_images(page, pix):
    """표와 이미지를 감지"""
    try:
        # 이미지 데이터 추출 및 변환 (안전하게 처리)
        img_data = np.frombuffer(pix.samples, dtype=np.uint8)
        
        # 이미지 차원 확인
        expected_size = pix.height * pix.width * pix.n
        if len(img_data) != expected_size:
            print(f"⚠️ 이미지 데이터 크기 불일치: 예상 {expected_size}, 실제 {len(img_data)}")
            return False, False
            
        # 올바른 형태로 reshape
        img_np = img_data.reshape(pix.height, pix.width, pix.n)
        
        # 색상 공간 변환
        if pix.n == 4:  # CMYK인 경우
            img_np = cv2.cvtColor(img_np, cv2.COLOR_CMYK2RGB)
        elif pix.n == 1:  # 그레이스케일인 경우
            img_np = cv2.cvtColor(img_np, cv2.COLOR_GRAY2RGB)
        
        # 그레이스케일로 변환
        gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
        
        # 에지 검출
        edges = cv2.Canny(gray, 50, 150, apertureSize=3)
        
        # 허프 변환으로 선 감지
        lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)
        
        # 표 감지 로직 (지금은 단순히 많은 가로/세로선이 있는지 확인)
        has_table = False
        if lines is not None and len(lines) > 10:
            horizontal_lines = 0
            vertical_lines = 0
            
            for line in lines:
                x1, y1, x2, y2 = line[0]
                if abs(x2 - x1) > abs(y2 - y1):  # 가로선
                    horizontal_lines += 1
                else:  # 세로선
                    vertical_lines += 1
            
            # 가로선과 세로선이 모두 일정 개수 이상이면 표로 간주
            has_table = horizontal_lines > 3 and vertical_lines > 3
        
        # 이미지 감지 (향후 구현)
        has_image = False
        
        return has_table, has_image
    
    except Exception as e:
        print(f"⚠️ 표/이미지 감지 중 오류 발생: {e}")
        return False, False

def pdf_to_hwpx(pdf_path, hwpx_path, ocr_lang=['ko', 'en'], use_gpu=False):
    """PDF 파일을 OCR로 변환하여 한글(HWPX) 파일로 저장 (개선된 버전)"""
    try:
        # PDF 파일 열기
        doc = fitz.open(pdf_path)
        
        # EasyOCR 초기화 (한글 및 영어 지원)
        reader = easyocr.Reader(ocr_lang, gpu=use_gpu, quantize=False)

        # 한글 문서 생성
        hwp = Hwp(new=True)
        hwp.Run("FileNew")
        hwp.XHwpWindows.Item(0).Visible = True

        # 페이지 설정 (여백 및 방향 설정)
        hwp.HAction.GetDefault("PageSetup", hwp.HParameterSet.HPageDef.HSet)
        page_settings = {
            "PaperDirection": 0,  # 0: 세로, 1: 가로
            "PaperType": 0,       # A4
            "LeftMargin": 1500,
            "RightMargin": 1500,
            "TopMargin": 1500,
            "BottomMargin": 1500,
            "HeaderLen": 500,
            "FooterLen": 500,
            "GutterLen": 0
        }
        for key, value in page_settings.items():
            hwp.HParameterSet.HPageDef.HSet.SetItem(key, value)
        hwp.HAction.Execute("PageSetup", hwp.HParameterSet.HPageDef.HSet)

        # 페이지별 OCR 처리
        for page_num in range(doc.page_count):
            print(f"처리 중: 페이지 {page_num+1}/{doc.page_count}")
            page = doc.load_page(page_num)
            
            try:
                # 고해상도 렌더링
                zoom = 3  # 해상도 증가
                mat = fitz.Matrix(zoom, zoom)
                pix = page.get_pixmap(matrix=mat, alpha=False)
                
                # 이미지 픽셀 데이터 검사
                if len(pix.samples) == 0:
                    print(f"⚠️ 페이지 {page_num+1}: 이미지 데이터가 비어 있습니다. 건너뜁니다.")
                    continue
                
                # CMYK 색상 처리
                if pix.colorspace and pix.colorspace.n == 4:  # CMYK 색상일 경우 RGB 변환
                    pix = fitz.Pixmap(fitz.csRGB, pix)
                
                # PyMuPDF 이미지를 PIL 이미지로 안전하게 변환
                try:
                    img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
                except ValueError as e:
                    print(f"⚠️ 이미지 변환 오류: {e}")
                    # 대체 방법 시도
                    img_array = np.frombuffer(pix.samples, dtype=np.uint8)
                    if len(img_array) == pix.width * pix.height * 3:  # RGB
                        img_array = img_array.reshape(pix.height, pix.width, 3)
                        img = Image.fromarray(img_array)
                    else:
                        print(f"🔍 이미지 형식 문제: 크기={len(img_array)}, 예상={pix.width * pix.height * pix.n}")
                        continue  # 이 페이지 건너뛰기
                
                # 이미지 전처리 (OCR 성능 향상)
                try:
                    enhanced_img = enhance_image_for_ocr(img)
                except Exception as e:
                    print(f"⚠️ 이미지 전처리 오류: {e}")
                    enhanced_img = img  # 원본 이미지 사용
                
                # 표와 이미지 감지 - 오류 발생 시 건너뛰기
                try:
                    has_table, has_image = detect_tables_and_images(page, pix)
                except Exception as e:
                    print(f"⚠️ 표/이미지 감지 오류: {e}")
                    has_table, has_image = False, False
                
                # 텍스트 및 서식 추출
                try:
                    # numpy 배열로 변환 (easyocr 요구사항)
                    img_np = np.array(enhanced_img)
                    formatted_results = extract_text_with_format(reader, img_np, zoom)
                    
                    if not formatted_results:
                        print(f"⚠️ 페이지 {page_num+1}: OCR 결과가 없습니다.")
                        formatted_results = []
                except Exception as e:
                    print(f"⚠️ OCR 처리 오류: {e}")
                    formatted_results = []
                
                # 텍스트 간격 정규화
                if formatted_results:
                    try:
                        normalized_lines = normalize_text_spacing(formatted_results)
                    except Exception as e:
                        print(f"⚠️ 텍스트 간격 정규화 오류: {e}")
                        # 기본 텍스트 구조 생성
                        normalized_lines = [[{'text': item['text'], 'prefix_spaces': ' ', 
                                            'is_bold': False, 'is_italic': False, 
                                            'is_underline': False, 'is_heading': False, 
                                            'font_size': 10} for item in formatted_results]]
                    
                    # 텍스트를 한글 문서에 적용
                    try:
                        apply_text_to_hwp(hwp, normalized_lines)
                    except Exception as e:
                        print(f"⚠️ 한글 문서 적용 오류: {e}")
                        # 단순 방식으로 텍스트만 삽입
                        for line in normalized_lines:
                            line_text = "".join([word['prefix_spaces'] + word['text'] for word in line])
                            if line_text.strip():
                                hwp.insert_text(line_text.strip() + "\n")
                
                # 페이지 분리 (마지막 페이지가 아닌 경우)
                if page_num < doc.page_count - 1:
                    hwp.Run("BreakPage")
            
            except Exception as e:
                print(f"⚠️ 페이지 {page_num+1} 처리 중 오류 발생: {e}")
                continue  # 다음 페이지로 계속

        # 파일 저장
        doc.close()
        hwp.SaveAs(hwpx_path)
        hwp.Quit()
        
        print(f"✅ PDF 파일 '{pdf_path}'에서 텍스트를 추출하여 '{hwpx_path}'로 저장했습니다.")
        print(f"   - 향상된 OCR, 서식 감지, 간격 조정이 적용되었습니다.")
        
        return True
    
    except FileNotFoundError:
        print(f"❌ 오류: '{pdf_path}' 파일을 찾을 수 없습니다.")
    except Exception as e:
        print(f"⚠️ 오류 발생: {str(e)}")
        import traceback
        traceback.print_exc()  # 자세한 오류 정보 출력
        if 'hwp' in locals():
            try:
                hwp.Quit()
            except:
                pass
    
    return False

# HWP에 텍스트 삽입 함수 보완 (인터페이스 확장)
def insert_text_to_hwp(hwp, text):
    """한글 문서에 텍스트 삽입 함수"""
    # 현재 커서 위치에 텍스트 삽입
    hwp.HAction.GetDefault("InsertText", hwp.HParameterSet.HInsertText.HSet)
    hwp.HParameterSet.HInsertText.HSet.Text = text
    hwp.HAction.Execute("InsertText", hwp.HParameterSet.HInsertText.HSet)

# HWP 모듈 확장 - insert_text 메서드 추가
Hwp.insert_text = insert_text_to_hwp

if __name__ == "__main__":
    pdf_file = r"C:\Users\jaeil\OneDrive\문서\카카오톡 받은 파일\법정검사 매뉴얼.pdf"
    hwpx_file = r"C:\Users\jaeil\OneDrive\문서\카카오톡 받은 파일\법정검사 매뉴얼.hwpx"
    
    # OCR 언어 설정 (한국어, 영어)
    ocr_lang = ['ko', 'en']
    
    # GPU 사용 여부 (GPU 사용 시 True로 변경)
    use_gpu = False
    
    # PDF를 HWPX로 변환
    pdf_to_hwpx(pdf_file, hwpx_file, ocr_lang, use_gpu)

def normalize_text_spacing(formatted_results):
    """텍스트 간격과 줄 구분을 조정"""
    # 세로 방향으로 정렬
    formatted_results.sort(key=lambda x: (x['bbox'][1], x['bbox'][0]))
    
    # 줄 그룹화
    lines = []
    current_line = []
    current_y = None
    
    for result in formatted_results:
        if current_y is None or abs(result['bbox'][1] - current_y) <= result['height'] * 0.5:
            current_line.append(result)
            current_y = result['bbox'][1] if current_y is None else current_y
        else:
            # 현재 줄 내 항목을 x좌표로 정렬
            current_line.sort(key=lambda x: x['bbox'][0])
            lines.append(current_line)
            current_line = [result]
            current_y = result['bbox'][1]
    
    if current_line:
        current_line.sort(key=lambda x: x['bbox'][0])
        lines.append(current_line)
    
    # 각 줄의 단어 간격 계산 및 정규화
    normalized_lines = []
    for line in lines:
        normalized_line = []
        prev_end_x = None
        
        for word in line:
            # 올바른 공백 추가
            if prev_end_x is not None:
                space_width = word['bbox'][0] - prev_end_x
                num_spaces = max(1, round(space_width / (word['width'] * 0.3)))
                
                # 간격이 충분히 넓다면 공백 추가
                if space_width > word['width'] * 0.3:
                    word['prefix_spaces'] = ' ' * num_spaces
                else:
                    word['prefix_spaces'] = ''
            else:
                word['prefix_spaces'] = ''
            
            normalized_line.append(word)
            prev_end_x = word['bbox'][2]
        
        normalized_lines.append(normalized_line)
    
    return normalized_lines

def apply_text_to_hwp(hwp, normalized_lines):
    """정규화된 텍스트를 한글 문서에 적용"""
    for line_idx, line in enumerate(normalized_lines):
        line_text = ""
        
        for word in line:
            # 글자 서식 설정
            char_shape = {
                "Size": word['font_size'],
                "Bold": word['is_bold'],
                "Italic": word['is_italic'],
                "Underline": word['is_underline']
            }
            
            # 제목으로 감지되었다면 추가 서식 적용
            if word['is_heading']:
                char_shape["Size"] = int(word['font_size'] * 1.2)  # 크기 키우기
                char_shape["Bold"] = True  # 제목은 볼드 처리
            
            # 서식 적용
            hwp.SetCharShape(char_shape)
            
            # 단어 앞에 적절한 공백 추가
            line_text += word['prefix_spaces'] + word['text']
        
        # 줄 추가
        if line_text.strip():
            hwp.insert_text(line_text.strip())
            
            # 다음 줄로 이동 (마지막 줄이 아닌 경우)
            if line_idx < len(normalized_lines) - 1:
                # 다음 줄과의 간격 계산
                current_y_end = max(word['bbox'][3] for word in line)
                next_y_start = min(word['bbox'][1] for word in normalized_lines[line_idx + 1])
                
                # 줄 간격이 충분히 넓으면 빈 줄 추가
                line_spacing = next_y_start - current_y_end
                avg_height = sum(word['height'] for word in line) / len(line)
                
                if line_spacing > avg_height * 1.5:
                    hwp.insert_text("\n\n")  # 빈 줄 추가
                else:
                    hwp.insert_text("\n")  # 일반 줄바꿈
            else:
                hwp.insert_text("\n")

def detect_tables_and_images(page, pix):
    """표와 이미지를 감지"""
    try:
        # 이미지 데이터 추출 및 변환 (안전하게 처리)
        img_data = np.frombuffer(pix.samples, dtype=np.uint8)
        
        # 이미지 차원 확인
        expected_size = pix.height * pix.width * pix.n
        if len(img_data) != expected_size:
            print(f"⚠️ 이미지 데이터 크기 불일치: 예상 {expected_size}, 실제 {len(img_data)}")
            return False, False
            
        # 올바른 형태로 reshape
        img_np = img_data.reshape(pix.height, pix.width, pix.n)
        
        # 색상 공간 변환
        if pix.n == 4:  # CMYK인 경우
            img_np = cv2.cvtColor(img_np, cv2.COLOR_CMYK2RGB)
        elif pix.n == 1:  # 그레이스케일인 경우
            img_np = cv2.cvtColor(img_np, cv2.COLOR_GRAY2RGB)
        
        # 그레이스케일로 변환
        gray = cv2.cvtColor(img_np, cv2.COLOR_RGB2GRAY)
        
        # 에지 검출
        edges = cv2.Canny(gray, 50, 150, apertureSize=3)
        
        # 허프 변환으로 선 감지
        lines = cv2.HoughLinesP(edges, 1, np.pi/180, 100, minLineLength=100, maxLineGap=10)
        
        # 표 감지 로직 (지금은 단순히 많은 가로/세로선이 있는지 확인)
        has_table = False
        if lines is not None and len(lines) > 10:
            horizontal_lines = 0
            vertical_lines = 0
            
            for line in lines:
                x1, y1, x2, y2 = line[0]
                if abs(x2 - x1) > abs(y2 - y1):  # 가로선
                    horizontal_lines += 1
                else:  # 세로선
                    vertical_lines += 1
            
            # 가로선과 세로선이 모두 일정 개수 이상이면 표로 간주
            has_table = horizontal_lines > 3 and vertical_lines > 3
        
        # 이미지 감지 (향후 구현)
        has_image = False
        
        return has_table, has_image
    
    except Exception as e:
        print(f"⚠️ 표/이미지 감지 중 오류 발생: {e}")
        return False, False

def pdf_to_hwpx(pdf_path, hwpx_path, ocr_lang=['ko', 'en'], use_gpu=False):
    """PDF 파일을 OCR로 변환하여 한글(HWPX) 파일로 저장 (개선된 버전)"""
    try:
        # PDF 파일 열기
        doc = fitz.open(pdf_path)
        
        # EasyOCR 초기화 (한글 및 영어 지원)
        reader = easyocr.Reader(ocr_lang, gpu=use_gpu, quantize=False)

        # 한글 문서 생성
        hwp = Hwp(new=True)
        hwp.Run("FileNew")
        hwp.XHwpWindows.Item(0).Visible = True

        # 페이지 설정 (여백 및 방향 설정)
        hwp.HAction.GetDefault("PageSetup", hwp.HParameterSet.HPageDef.HSet)
        page_settings = {
            "PaperDirection": 0,  # 0: 세로, 1: 가로
            "PaperType": 0,       # A4
            "LeftMargin": 1500,
            "RightMargin": 1500,
            "TopMargin": 1500,
            "BottomMargin": 1500,
            "HeaderLen": 500,
            "FooterLen": 500,
            "GutterLen": 0
        }
        for key, value in page_settings.items():
            hwp.HParameterSet.HPageDef.HSet.SetItem(key, value)
        hwp.HAction.Execute("PageSetup", hwp.HParameterSet.HPageDef.HSet)

        # 페이지별 OCR 처리
        for page_num in range(doc.page_count):
            print(f"처리 중: 페이지 {page_num+1}/{doc.page_count}")
            page = doc.load_page(page_num)
            
            try:
                # 고해상도 렌더링
                zoom = 3  # 해상도 증가
                mat = fitz.Matrix(zoom, zoom)
                pix = page.get_pixmap(matrix=mat, alpha=False)
                
                # 이미지 픽셀 데이터 검사
                if len(pix.samples) == 0:
                    print(f"⚠️ 페이지 {page_num+1}: 이미지 데이터가 비어 있습니다. 건너뜁니다.")
                    continue
                
                # CMYK 색상 처리
                if pix.colorspace and pix.colorspace.n == 4:  # CMYK 색상일 경우 RGB 변환
                    pix = fitz.Pixmap(fitz.csRGB, pix)
                
                # PyMuPDF 이미지를 PIL 이미지로 안전하게 변환
                try:
                    img = Image.frombytes("RGB", [pix.width, pix.height], pix.samples)
                except ValueError as e:
                    print(f"⚠️ 이미지 변환 오류: {e}")
                    # 대체 방법 시도
                    img_array = np.frombuffer(pix.samples, dtype=np.uint8)
                    if len(img_array) == pix.width * pix.height * 3:  # RGB
                        img_array = img_array.reshape(pix.height, pix.width, 3)
                        img = Image.fromarray(img_array)
                    else:
                        print(f"🔍 이미지 형식 문제: 크기={len(img_array)}, 예상={pix.width * pix.height * pix.n}")
                        continue  # 이 페이지 건너뛰기
                
                # 이미지 전처리 (OCR 성능 향상)
                try:
                    enhanced_img = enhance_image_for_ocr(img)
                except Exception as e:
                    print(f"⚠️ 이미지 전처리 오류: {e}")
                    enhanced_img = img  # 원본 이미지 사용
                
                # 표와 이미지 감지 - 오류 발생 시 건너뛰기
                try:
                    has_table, has_image = detect_tables_and_images(page, pix)
                except Exception as e:
                    print(f"⚠️ 표/이미지 감지 오류: {e}")
                    has_table, has_image = False, False
                
                # 텍스트 및 서식 추출
                try:
                    # numpy 배열로 변환 (easyocr 요구사항)
                    img_np = np.array(enhanced_img)
                    formatted_results = extract_text_with_format(reader, img_np, zoom)
                    
                    if not formatted_results:
                        print(f"⚠️ 페이지 {page_num+1}: OCR 결과가 없습니다.")
                        formatted_results = []
                except Exception as e:
                    print(f"⚠️ OCR 처리 오류: {e}")
                    formatted_results = []
                
                # 텍스트 간격 정규화
                if formatted_results:
                    try:
                        normalized_lines = normalize_text_spacing(formatted_results)
                    except Exception as e:
                        print(f"⚠️ 텍스트 간격 정규화 오류: {e}")
                        # 기본 텍스트 구조 생성
                        normalized_lines = [[{'text': item['text'], 'prefix_spaces': ' ', 
                                            'is_bold': False, 'is_italic': False, 
                                            'is_underline': False, 'is_heading': False, 
                                            'font_size': 10} for item in formatted_results]]
                    
                    # 텍스트를 한글 문서에 적용
                    try:
                        apply_text_to_hwp(hwp, normalized_lines)
                    except Exception as e:
                        print(f"⚠️ 한글 문서 적용 오류: {e}")
                        # 단순 방식으로 텍스트만 삽입
                        for line in normalized_lines:
                            line_text = "".join([word['prefix_spaces'] + word['text'] for word in line])
                            if line_text.strip():
                                hwp.insert_text(line_text.strip() + "\n")
                
                # 페이지 분리 (마지막 페이지가 아닌 경우)
                if page_num < doc.page_count - 1:
                    hwp.Run("BreakPage")
            
            except Exception as e:
                print(f"⚠️ 페이지 {page_num+1} 처리 중 오류 발생: {e}")
                continue  # 다음 페이지로 계속

        # 파일 저장
        doc.close()
        hwp.SaveAs(hwpx_path)
        hwp.Quit()
        
        print(f"✅ PDF 파일 '{pdf_path}'에서 텍스트를 추출하여 '{hwpx_path}'로 저장했습니다.")
        print(f"   - 향상된 OCR, 서식 감지, 간격 조정이 적용되었습니다.")
        
        return True
    
    except FileNotFoundError:
        print(f"❌ 오류: '{pdf_path}' 파일을 찾을 수 없습니다.")
    except Exception as e:
        print(f"⚠️ 오류 발생: {str(e)}")
        import traceback
        traceback.print_exc()  # 자세한 오류 정보 출력
        if 'hwp' in locals():
            try:
                hwp.Quit()
            except:
                pass
    
    return False

# HWP에 텍스트 삽입 함수 보완 (인터페이스 확장)
def insert_text_to_hwp(hwp, text):
    """한글 문서에 텍스트 삽입 함수"""
    # 현재 커서 위치에 텍스트 삽입
    hwp.HAction.GetDefault("InsertText", hwp.HParameterSet.HInsertText.HSet)
    hwp.HParameterSet.HInsertText.HSet.Text = text
    hwp.HAction.Execute("InsertText", hwp.HParameterSet.HInsertText.HSet)

# HWP 모듈 확장 - insert_text 메서드 추가
Hwp.insert_text = insert_text_to_hwp

if __name__ == "__main__":
    pdf_file = r"C:\Users\jaeil\OneDrive\문서\카카오톡 받은 파일\법정검사 매뉴얼.pdf"
    hwpx_file = r"C:\Users\jaeil\OneDrive\문서\카카오톡 받은 파일\법정검사 매뉴얼.hwpx"
    
    # OCR 언어 설정 (한국어, 영어)
    ocr_lang = ['ko', 'en']
    
    # GPU 사용 여부 (GPU 사용 시 True로 변경)
    use_gpu = False
    
    # PDF를 HWPX로 변환
    pdf_to_hwpx(pdf_file, hwpx_file, ocr_lang, use_gpu)