디시인사이드 갤러리

갤러리 이슈박스, 최근방문 갤러리

갤러리 본문 영역

북스캔 파이썬 코드 퍼블릭 도메인 (1)

몬발켜갤로그로 이동합니다. 2024.04.30 12:37:03
조회 55 추천 1 댓글 0

<내가 chatGPT4랑 의논해서 만든 코드임... 다른 사람 코드는 전혀 들어있지 않음. 마음대로 쓰시라고 공개함.>


import cv2
import os
import numpy as np
import sys

folder_path = "C:/input" # 작업하려는 폴더 경로
file_list = os.listdir(folder_path)

image_extensions = [".jpg", ".jpeg", ".png"] # 그림 파일만 불러온다
image_files = [file for file in file_list if any(file.lower().endswith(ext) for ext in image_extensions)]

# 각 파일을 하나씩 불러온다
for image_name in image_files:

# 이미지 파일을 불러온다
image = cv2.imread("C:\\input\\{}".format(image_name))

# 그레이 스케일 및 이진화
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
_, binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU )

# 컨투어 찾기
contours, _ = cv2.findContours(binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 가장 큰 컨투어 찾기
largest_contour = max(contours, key=cv2.contourArea)

# 가장 큰 컨투어에 불필요한 점/점들이 포함된 경우가 종종 발생하기 때문에 제거할 필요가 있다
# 새로운 이미지 생성 (검은색 배경)
new_image = np.zeros_like(binary)

# 가장 큰 컨투어 중에서 면적이 가장 큰 폐곡선 찾기
largest_closed_contour = max([c for c in contours if cv2.contourArea(c) > 0], key=cv2.contourArea)

# 면적이 가장 큰 폐곡선 안에 있는 흰색 점들만 남기고 나머지는 삭제하여 새 이미지에 저장
cv2.drawContours(new_image, [largest_closed_contour], -1, (255), thickness=cv2.FILLED)

# 컨투어를 둘러싼 가장 작은 사각형 찾기
min_rect = cv2.minAreaRect(largest_closed_contour)

# minAreaRect에서 반환한 4개 점은 실수값을 갖으므로, 사용하려면 정수로 변환한다
box_points = cv2.boxPoints(min_rect)
box_points = np.intp(box_points)

# 4개 점을 좌표값에 따라서 번호를 부여한다
# 원래의 의도는 좌상, 우상, 좌하, 우하 순서로 P1, P2, P3, P4를 부여하려고 하였다
# 그러나 프로그래머의 일반적인 코드 규칙에 따라서 점의 번호를 부여하기로 생각을 바꿨다.
# The order will be P1 (top-left), P2 (top-right), P3 (bottom-left), P4 (bottom-right)
box_points = sorted(box_points, key=lambda x: (x[1], x[0]))
if box_points[0][0] > box_points[1][0]:
box_points[0], box_points[1] = box_points[1], box_points[0]
if box_points[2][0] > box_points[3][0]:
box_points[2], box_points[3] = box_points[3], box_points[2]

# 프로그래머의 일반적인 코드 부여 방법에 따라서 점의 번호를 정했다
P1 = box_points[0]
P2 = box_points[1]
P3 = box_points[2]
P4 = box_points[3]

if P1[0] < P2[0]: # 기울기가 양수일 때(왼쪽으로 기울었다:시계방향으로 회전해야 한다)
x1, y1 = P1[0], P1[1]
x2, y2 = P2[0], P2[1]

# 기울기 slope를 계산한다.
delta_x = x2 - x1
delta_y = y2 - y1
slope = delta_y / delta_x if delta_x != 0 else None

# 기울기에 따라서 회전할 각과 방향을 계산한다
# Calculate the angle in radians and then convert to degrees
# The angle must be negative for a clockwise rotation
angle_of_rotation = -np.degrees(np.arctan(slope))

# 시계방향으로 angle만큼 회전하고, 변수에 저장한다
# center에 들어갈 점 P의 좌표는 데이터형을 변환해야 한다
center = (int(P1[0]), int(P1[1]))
angle = -angle_of_rotation
M = cv2.getRotationMatrix2D(center, angle, 1)
rotated_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

# 회전한 이미지를 저장하지 않고 변수를 바로 사용하여 다음 단계의 작업을 진행한다
#그레이 스케일 및 이진화
gray1 = cv2.cvtColor(rotated_image, cv2.COLOR_BGR2GRAY)
_, binary1 = cv2.threshold(gray1, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU )

# 회전한 이미지의 컨투어 찾기
contours1, _ = cv2.findContours(binary1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 회전한 이미지의 가장 큰 컨투어 찾기
largest_contour1 = max(contours1, key=cv2.contourArea)

# 새로운 이미지 생성 (검은색 배경)
new_image1 = np.zeros_like(binary1)

# 가장 큰 컨투어에 불필요한 점/점들이 포함된 경우가 종종 발생하기 때문에 제거할 필요가 있다
# 회전한 이미지의 가장 큰 컨투어 중에서 면적이 가장 큰 폐곡선 찾기
largest_closed_contour1 = max([c for c in contours1 if cv2.contourArea(c) > 0], key=cv2.contourArea)

# 면적이 가장 큰 폐곡선 안에 있는 흰색 점들만 남기고 나머지는 삭제하여 새 이미지에 저장
cv2.drawContours(new_image1, [largest_closed_contour1], -1, (255), thickness=cv2.FILLED)

# 회전한 이미지의 컨투어를 포함하는 가장 작은 사각형을 찾는다
min_rect1 = cv2.minAreaRect(largest_closed_contour1)

# minAreaRect에서 반환한 4개 점은 실수값을 갖으므로, 사용하려면 정수로 변환한다
# Convert it to box points (four points)
box_points1 = cv2.boxPoints(min_rect1)
box_points1 = np.intp(box_points1)

# # 4개 점을 좌표값에 따라서 번호를 부여한다
# 원래의 의도는 좌상, 우상, 좌하, 우하 순서로 P1, P2, P3, P4를 부여하려고 하였다
# 그러나 프로그래머의 일반적인 코드 규칙에 따라서 점의 번호를 부여하기로 생각을 바꿨다.
# The order will be P1 (top-left), P2 (top-right), P3 (bottom-left), P4 (bottom-right)
box_points1 = sorted(box_points1, key=lambda x: (x[1], x[0]))
if box_points1[0][0] > box_points1[1][0]:
box_points1[0], box_points1[1] = box_points1[1], box_points1[0]
if box_points1[2][0] > box_points1[3][0]:
box_points1[2], box_points1[3] = box_points1[3], box_points1[2]

# 프로그래머의 일반적인 코드 부여 방법에 따라서 점의 번호를 정했다
# 점의 번호를 앞의 점과 다르게 해서 혼동을 피했다
P11 = box_points1[0]
P22 = box_points1[1]
P33 = box_points1[2]
P44 = box_points1[3]
# 4개 점의 좌표를 이용하여 사각형 영역을 택하여 새 그림 파일로 저장한다
k = rotated_image[P11[1]:P33[1], P11[0]:P22[0]]

cv2.imwrite("C:\\output\\{}".format(image_name), k)

else: # 기울기가 양수가 아닐 때(오른쪽으로 기울었다:반시계방향으로 회전해야 한다)

x1, y1 = P1[0], P1[1]
x2, y2 = P2[0], P2[1]

# 기울기를 계산한다
delta_x = x2 - x1
delta_y = y2 - y1
slope = delta_y / delta_x if delta_x != 0 else None

# 기울기에 따라서 회전할 각과 방향을 계산한다
# If the slope is zero (horizontal line), we do not need to rotate.
# If the slope is negative or undefined (vertical line), we rotate counterclockwise.
# The angle must be positive for a counterclockwise rotation
angle_of_rotation = np.degrees(np.arctan(-slope)) if slope is not None else 90

# 반시계방향으로 angle만큼 회전하여 변수에 저장한다
# center에 들어갈 점 P의 좌표는 데이터형을 변환해야 한다
center = (int(P1[0]), int(P1[1]))
angle = angle_of_rotation
M = cv2.getRotationMatrix2D(center, angle, 1)
rotated_image = cv2.warpAffine(image, M, (image.shape[1], image.shape[0]))

# 회전한 이미지를 저장하지 않고 변수를 바로 사용하여 다음 단계의 작업을 진행한다
#그레이 스케일 및 이진화
gray1 = cv2.cvtColor(rotated_image, cv2.COLOR_BGR2GRAY)
_, binary1 = cv2.threshold(gray1, 127, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU )

# 회전한 이미지의 컨투어 찾기
contours1, _ = cv2.findContours(binary1, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

# 회전한 이미지의 가장 큰 컨투어 찾기
largest_contour1 = max(contours1, key=cv2.contourArea)

# 새로운 이미지 생성 (검은색 배경)
new_image1 = np.zeros_like(binary1)

# 회전한 이미지의 가장 큰 컨투어 중에서 면적이 가장 큰 폐곡선 찾기
largest_closed_contour1 = max([c for c in contours1 if cv2.contourArea(c) > 0], key=cv2.contourArea)

# 면적이 가장 큰 폐곡선 안에 있는 흰색 점들만 남기고 나머지는 삭제하여 새 이미지에 저장
cv2.drawContours(new_image1, [largest_closed_contour1], -1, (255), thickness=cv2.FILLED)

# 회전한 이미지의 컨투어를 포함하는 가장 작은 사각형을 찾는다
min_rect1 = cv2.minAreaRect(largest_closed_contour1)

# minAreaRect에서 반환한 4개 점은 실수값을 갖으므로, 사용하려면 정수로 변환한다
# Convert it to box points (four points)
box_points1 = cv2.boxPoints(min_rect1)
box_points1 = np.intp(box_points1)

# 4개 점을 좌표값에 따라서 번호를 부여한다
# 원래의 의도는 좌상, 우상, 좌하, 우하 순서로 P1, P2, P3, P4를 부여하려고 하였다
# 그러나 프로그래머의 일반적인 코드 규칙에 따라서 점의 번호를 부여하기로 생각을 바꿨다.
# The order will be P1 (top-left), P2 (top-right), P3 (bottom-left), P4 (bottom-right)
box_points1 = sorted(box_points1, key=lambda x: (x[1], x[0]))
if box_points1[0][0] > box_points1[1][0]:
box_points1[0], box_points1[1] = box_points1[1], box_points1[0]
if box_points1[2][0] > box_points1[3][0]:
box_points1[2], box_points1[3] = box_points1[3], box_points1[2]

# 프로그래머의 일반적인 코드 부여 방법에 따라서 점의 번호를 정했다
# 점의 번호를 앞의 점과 다르게 해서 혼동을 피했다
P11 = box_points1[0]
P22 = box_points1[1]
P33 = box_points1[2]
P44 = box_points1[3]
# 4개 점의 좌표를 이용하여 사각형 영역을 택하여 새 그림 파일로 저장한다
k = rotated_image[P11[1]:P33[1], P11[0]:P22[0]]

cv2.imwrite("C:\\output\\{}".format(image_name), k)


sys.exit()



추천 비추천

1

고정닉 1

0

댓글 영역

전체 댓글 0
등록순정렬 기준선택
본문 보기

하단 갤러리 리스트 영역

왼쪽 컨텐츠 영역

갤러리 리스트 영역

갤러리 리스트
번호 제목 글쓴이 작성일 조회 추천
설문 어떤 상황이 닥쳐도 지갑 절대 안 열 것 같은 스타는? 운영자 24/05/20 - -
2698349 친구가 개발자 취업 준비중인데 ㅈ소도 경쟁률 500:1 이따구로 찍힌다던 [4] ㅇㅇ(39.7) 05.21 118 0
2698348 "테크업계 취업문 좁아져…美 대학 컴사 취업 따논 당상 옛말" ㅇㅇ(106.102) 05.21 37 1
2698347 코딩 독학하는데 일케 해도되나? [4] ㅇㅅ(175.223) 05.21 60 1
2698346 독일처럼 노동법원 설치한다고 함 [2] ㅇㅇ(49.142) 05.21 43 0
2698345 요즘 컨디션이 영 별로네 아스카영원히사랑해갤로그로 이동합니다. 05.21 19 0
2698344 냥덩이의 소중한 친구가 되어 주세양❤+ [1] ♥순수퓨어냥덩♥갤로그로 이동합니다. 05.21 29 0
2698343 아니일하는년들중에업무하는데남이말하는데응응이지랄하는새끼는뭐냐? [2] 보법E노무현갤로그로 이동합니다. 05.21 42 0
2698342 코딩 취업 그정도 아닌데 여기애들 뭐임? [4] ㅇㅇ(106.101) 05.21 172 2
2698341 보듬 컴퍼니는 양쪽 입장 들어봐야 알지않나 프갤러(211.209) 05.21 29 0
2698338 네이티브 안드로이드 썩은 동앗줄이야? [8] ㅇㅇ(106.101) 05.21 88 0
2698337 3일차 ♥꽁꽁얼어버린냇물위에냥덩♥갤로그로 이동합니다. 05.21 29 0
2698336 RN 개발자 맥북 에어로 가능할까요? [2] ㅇㅇ(112.172) 05.21 59 0
2698335 노무현 나오는 미연시.jpg 메쿠이로갤로그로 이동합니다. 05.21 30 0
2698333 하 시발 공장이라도 갈까 [16] ㅇㅇ(182.226) 05.21 124 0
2698332 미국 송환이 보류됐다. 영국 법원이 내무부 행정 명령에 대해 영국 조커@두팩트수보(175.117) 05.21 20 0
2698330 서울대에서 디지털 성범죄 사건이 발생해 경찰이 수사 중이다. 20일 경 조커@두팩트수보(175.117) 05.21 40 0
2698329 나는내향적이야 ㅇㅇ(223.39) 05.21 24 0
2698328 뷰지는그냥안에싸면말들음ㅇㅇ쌋는데또ㅈㄹ한다?또싸 보법E노무현갤로그로 이동합니다. 05.21 39 0
2698327 강형욱이 회사를 폐업한 진짜 이유 폭로 딘퐁갤로그로 이동합니다. 05.21 95 1
2698326 강형욱 폐업 충격적아님? [3] 헬마스터갤로그로 이동합니다. 05.21 183 1
2698321 음기 충전 발명도둑잡기갤로그로 이동합니다. 05.21 45 0
2698316 요즘 프로그래머들은 왜 서비스개발쪽만 많은거야? [6] 프갤러(14.39) 05.21 132 0
2698312 ‘베테랑2’만 칸 간다…‘넥스트 박찬욱·봉준호’ 전무한 한국영화계, 위기 [1] 발명도둑잡기갤로그로 이동합니다. 05.21 51 0
2698309 "기적의 하나님, 김호중 위해 기도해주세요"…팬들 반응이 발명도둑잡기갤로그로 이동합니다. 05.21 59 0
2698302 2020 평화의나무합창단 기획공연 10. 인간의 노래 발명도둑잡기갤로그로 이동합니다. 05.21 14 0
2698300 딱국아 거봐 너무 껄떡거리면 여자가 무서워 한댔잖아 발명도둑잡기갤로그로 이동합니다. 05.21 28 0
2698299 요즘 잠이 안오네 [4] ㅇㅇ(121.181) 05.21 46 0
2698298 David Bowie - Lazarus 발명도둑잡기갤로그로 이동합니다. 05.21 17 0
2698296 "故김주혁의 냄새가 김선호에게 난다"..17년 만에 돌아온 홍반장 '갯마 발명도둑잡기갤로그로 이동합니다. 05.21 70 0
2698295 아 짝녀한테 뭐든지 다해주고싶다 [2] 딱꾹(61.99) 05.21 74 0
2698293 '4대 루머' 나훈아, 괴소문과 해명 (종합) [1] 발명도둑잡기갤로그로 이동합니다. 05.21 39 0
2698291 원래 수컷들은 불쌍해.. [1] 딱꾹(61.99) 05.21 28 0
2698290 딱꾹이와 조르디와 류류는 분명히 가짜다. 내 옛날통피쓴다. 도리스아(119.195) 05.21 27 0
2698288 시노자키 아이 "이홍기와 여행? 갔지만 단둘 아냐" 의혹 해명 [1] 발명도둑잡기갤로그로 이동합니다. 05.21 44 0
2698286 한중수교 10주년 특별기획드라마 <링링> 발명도둑잡기갤로그로 이동합니다. 05.21 21 0
2698285 딱국은 진짜 여자 왜이렇게 좋아하는거지 ㅠㅠㅠ [1] 딱꾹(61.99) 05.21 19 0
2698283 딱국은 여자웃음소리만 듣고도.. 가능해.. [6] 딱꾹(61.99) 05.21 43 0
2698282 진짜 오만가지 생각이 다들음 [1] 딱꾹(61.99) 05.21 33 0
2698279 좋아하는 여자가 웃는거 볼때 수컷의 마음 생각 [1] 딱꾹(61.99) 05.21 30 0
2698278 남자들은 좋아하는여자가 웃어주기만하면 딱꾹(61.99) 05.21 27 0
2698276 아 짝녀가 너무 좋아 ㅠㅠㅠㅠ 딱꾹(61.99) 05.21 17 0
2698275 나 근데 짝녀한테 나도모르게 막 노예짓하게됨 [1] 딱꾹(61.99) 05.21 33 0
2698274 Windows Canvas Toile 사용해보기로 했다. 도리스아(119.195) 05.21 47 0
2698272 나 여친생기면 진짜 세상에서 제일 행복하게 해줄건데 [1] 딱꾹(61.99) 05.21 30 0
2698271 유명인이 나락가면 전국민이 돌 하나씩 던지는데 [2] 헬마스터갤로그로 이동합니다. 05.21 33 0
2698270 조르디 왠지 못생겼을거같은데 딱꾹(61.99) 05.21 29 0
2698269 아 이쁘고 매력있구 성격좋은여자는 다 남자물고있음 딱꾹(61.99) 05.21 22 0
2698268 오은영 박사가 말하는 ‘기 센 사람’ 특징 . jpg 발명도둑잡기갤로그로 이동합니다. 05.21 34 0
2698267 강형욱 보듬컴퍼니 폐업하네 헬마스터갤로그로 이동합니다. 05.21 222 0
2698265 음악심리: 장르와 사람 성격의 상관관계, 팬의 심리 발명도둑잡기갤로그로 이동합니다. 05.21 35 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2