디시인사이드 갤러리

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

갤러리 본문 영역

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

몬발켜갤로그로 이동합니다. 2024.04.30 12:37:03
조회 53 추천 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 - -
2698236 <하드코어 헨리>, <서치> 관련 생각나는 예전글 발명도둑잡기갤로그로 이동합니다. 01:08 13 0
2698235 금투세 도입하니 부동산 또오르네 시발 ㅇㅇ(118.235) 00:58 30 0
2698234 공부 좆도 안하고 놀기만 하는 고딩임 [1] 프갤러(125.186) 00:57 42 0
2698233 취준생 꿀팀: 스타트업 들어갈때 투자 언제 받았는지 꼭 확인해라 [7] 초코냥갤로그로 이동합니다. 00:53 107 0
2698232 지금 스타트업 투자라운지 보면 95%가 2021년 이후 받은거 없음 초코냥갤로그로 이동합니다. 00:46 50 0
2698231 오늘의 소설, 영화 실마리: 잠자는 사람과 깨어있는 사람이 텔레파시 [1] 발명도둑잡기갤로그로 이동합니다. 00:42 17 0
2698230 링크드인에 스타트업 파산 또 올라옴 [4] 초코냥갤로그로 이동합니다. 00:41 126 1
2698228 미래의 어느 역사학자들의 대화라는데 (요약편) 프갤러(211.241) 00:31 29 0
2698227 미래의 어느 역사학자들의 대화라는데 프갤러(211.241) 00:29 33 0
2698226 ㅇㅅㅇ [1] 류류(121.160) 00:24 20 0
2698225 류류 저새끼 프갤에서 몰아내자 [2] 초코냥갤로그로 이동합니다. 00:23 63 0
2698222 미소녀 젖 줘 잠지 줘 아기 낳아죠 태반 줘 ㅇㅅㅇ 류류(121.160) 00:09 20 1
2698221 미소녀 여자아이 성기는 자지로 박으라고 있는거임 류류(121.160) 00:09 21 1
2698220 나 좋아하는 여자 프사보고 ㄸ친거 범죄야? [9] 딱꾹(113.198) 00:06 58 0
2698219 미소녀 여자아이 젖꼭지 혀로 계속 굴릴거임 ㅇㅅㅇ 류류(121.160) 00:05 16 1
2698218 미소녀 여자아이 젖꼭지 모유나올때까지 빨거임 류류(121.160) 00:02 24 1
2698217 아 미소녀 여자아이 젖꼭지를 쪽쪽 ㅇㅅㅇ 류류(121.160) 00:02 16 1
2698216 여자아이 유방 주무르고 싶음 ㅇㅅㅇ [3] 류류(121.160) 05.20 30 1
2698215 네가 그래도 양심이 있는데 일반인 보고 그거 안한다. 도리스아(119.195) 05.20 19 0
2698214 코파일럿 외않씀? 프갤러(118.235) 05.20 21 0
2698213 서울대생 음란물 걸렸되요. [1] 도리스아(119.195) 05.20 53 1
2698212 딱국과 최원종 관계 제보 받는다. rockon01@naver.com 조커@두팩트수보(175.117) 05.20 12 1
2698211 오늘 헬쓰장에서 트레드밀 뛰면서 영화 <마일22>를 봤다 발명도둑잡기갤로그로 이동합니다. 05.20 13 0
2698210 전공 비전공 차이크냐? [1] 프갤러(118.235) 05.20 55 0
2698209 따꾸기 땜 [2] 조커@두팩트수보(175.117) 05.20 24 0
2698208 컴공갈바에 전자공갔으면 초봉1.5배는 더 받았을듯 [6] 프갤러(112.187) 05.20 76 0
2698207 갤기장은 결국 나님을 버륀 거야 ㅇㅅㅇ [2] 나트륨찡갤로그로 이동합니다. 05.20 21 0
2698206 친구 업는 나틂륨은 ㅇㅅㅇ [2] 나트륨찡갤로그로 이동합니다. 05.20 29 1
2698205 개발자vs9급 [1] 프갤러(118.235) 05.20 43 0
2698204 음식 잘옷먹은듯.. 체한거 같다.. [1] ♥꽁꽁얼어버린냇물위에냥덩♥갤로그로 이동합니다. 05.20 30 0
2698203 술먹고 토하는 사람 없냐??오늘 술몇잔 쳐먹고 안취하겠다고 쪼다마냥 토함 [2] ㅇㅇ(223.38) 05.20 44 0
2698202 신입 SI개발자가 동안이라서 좋은 점 [3] ㅇㅇ갤로그로 이동합니다. 05.20 110 1
2698201 성욕해소에는 [6] 멍청한유라ㅋ갤로그로 이동합니다. 05.20 69 1
2698200 아래 성욕 때문에 고민한다는 남자 발명도둑잡기갤로그로 이동합니다. 05.20 22 0
2698199 mysql db 이미지로 인스턴스 띄우는거 어려움? [2] 프갤러(175.213) 05.20 96 0
2698198 5월인데 벌써 모기가 있네 ㅇㅅㅇ [2] 류류(121.160) 05.20 23 0
2698197 9to4,10to5에 주4일 직장이 최고임 ♥꽁꽁얼어버린냇물위에냥덩♥갤로그로 이동합니다. 05.20 34 0
2698196 따꾸기 발정난거만 용서해주면 안됑? ㅠㅠㅠ [2] 딱국(113.198) 05.20 27 0
2698195 운덩 강도를 낮추고 빈도를 늘려야겠음 [7] ♥꽁꽁얼어버린냇물위에냥덩♥갤로그로 이동합니다. 05.20 39 0
2698194 진척 딱군 따랑햇 ㅠㅠ 딱국이랑 동맹맺쟝 [1] 딱국(113.198) 05.20 18 0
2698193 이제 자자 [2] 멍청한유라ㅋ갤로그로 이동합니다. 05.20 36 0
2698192 직구 관련 내용 정리해준다 cvs.갤로그로 이동합니다. 05.20 21 0
2698191 취업한지 6개월된 신입인데 이거 ㅈ된거냐?? [3] 프갤러(59.18) 05.20 135 2
2698190 민주당 갤러리 vs 국힘 갤러리 연령대 비교..JPG 발명도둑잡기갤로그로 이동합니다. 05.20 37 0
2698188 DIY Cardboard FM Synth (8 DX7s!) | MiniD 발명도둑잡기갤로그로 이동합니다. 05.20 9 0
2698187 아니 이거 토스가 아니라 국비라고? [1] 딘퐁갤로그로 이동합니다. 05.20 110 0
2698185 말세입니다. 이거 엄청 좊습니다. 도리스아(119.195) 05.20 26 0
2698184 부캠 추천좀 NHN 아카데미 vs 유플러스 유레카 [4] 프갤러(125.241) 05.20 60 0
2698182 7to4기업 어때? [3] 멍유바라기(112.169) 05.20 40 0
2698181 #PICOmputer 28 - latest universal PICO c 발명도둑잡기갤로그로 이동합니다. 05.20 8 0
갤러리 내부 검색
제목+내용게시물 정렬 옵션

오른쪽 컨텐츠 영역

실시간 베스트

1/8

뉴스

디시미디어

디시이슈

1/2