| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | 5 | 6 | |
| 7 | 8 | 9 | 10 | 11 | 12 | 13 |
| 14 | 15 | 16 | 17 | 18 | 19 | 20 |
| 21 | 22 | 23 | 24 | 25 | 26 | 27 |
| 28 | 29 | 30 |
- Android
- Eclipse
- Spring
- vaadin
- NPM
- GIT
- 보조정렬
- mapreduce
- 공정능력
- Python
- Java
- xPlatform
- tomcat
- es6
- SQL
- hadoop
- SSL
- plugin
- Kotlin
- table
- MSSQL
- SPC
- Sqoop
- JavaScript
- react
- R
- mybatis
- Express
- window
- IntelliJ
- Today
- Total
DBILITY
python opencv 기초 학습 정리 본문
학습 내용을 정리한다. 정리해야 흐린 기억이라도 그려지니까.
설치부터 한다.pip install opencv-python
C:\Dev64\workspace\python_execise>pip install opencv-python
Collecting opencv-python
Downloading opencv_python-4.13.0.92-cp37-abi3-win_amd64.whl.metadata (20 kB)
Requirement already satisfied: numpy>=2 in C:\Python\Python313\Lib\site-packages (from opencv-python) (2.4.0)
Downloading opencv_python-4.13.0.92-cp37-abi3-win_amd64.whl (40.2 MB)
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 40.2/40.2 MB 9.0 MB/s 0:00:04
Installing collected packages: opencv-python
Successfully installed opencv-python-4.13.0.92
C:\Dev64\workspace\python_execise>py -c "import cv2; print(cv2.__version__)"
4.13.0
이미지를 읽어 출력하고 키입력이 있으면 창을 닫는 코드다.
import cv2
img = cv2.imread("sample.png") #이미지 읽기
cv2.imshow("img",img) #이미지 출력
cv2.waitKey(0) #키보드입력 대기
cv2.imwrite("copy_sample.png",img) #이미지 저장
cv2.destroyAllWindows() # 모든창 종료
opencv의 색상은 RGB가 아닌 BGR순서
import cv2
img = cv2.imread("sample.png")
height, width, channel = img.shape; #이미지 크기 확인
print(f"image size : {width}x{height}, channel : {channel}")
b, g, r = cv2.split(img) #색상 채널 분리 (B,G,R)
cv2.imshow("Red Channel", r)
cv2.imshow("Green Channel", g)
cv2.imshow("Blue Channel", b)
img = cv2.merge([b,g,r]) #색상 채널 병합, 이경우는 원복색상
cv2.imshow("img", img)
img = cv2.merge([r, g, b]) #색상 채널 병합, r/g/b로 치환?
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
이미지크기 조절
import cv2
img = cv2.imread("sample.png")
height, width, channel = img.shape;
resized = cv2.resize(img, (width * 2, height * 2))
cv2.imshow("resized", resized)
resized_ratio = cv2.resize(img, (0, 0), fx=0.5, fy=0.5)
cv2.imshow("resized_ratio", resized_ratio)
resized_fixed = cv2.resize(img, (300, 300))
cv2.imshow("resized_fixed", resized_fixed)
cv2.waitKey(0)
cv2.destroyAllWindows()
이미지 회전
import cv2
img = cv2.imread("sample.png")
cv2.imshow("img",img)
rotated = cv2.rotate(img, cv2.ROTATE_90_CLOCKWISE)
cv2.imshow("rotated", rotated)
cv2.waitKey(0)
cv2.destroyAllWindows()
이미지 자르기
import cv2
img = cv2.imread("sample.png")
cv2.imshow("img", img)
height, width, channel = img.shape;
# 좌표 : img[ y_start:y_end, x_start:x_end ]
cropped = img[0:int(height / 2), 0:int(width / 2)]
cv2.imshow("cropped", cropped)
cv2.waitKey(0)
cv2.destroyAllWindows()
그레이스케일 변환 ( 연산속도증가, 에지(윤곽선) 탐지 용이 , 조명변화민감도 저감 장점 )
import cv2
img = cv2.imread("sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cv2.imshow("gray", gray)
cv2.waitKey(0)
cv2.destroyAllWindows()
이진화(Thresholding) - 그레이스케일 이미지를 흑백(0,255)로 구분, 기준값(127)보다 밝으면 흰색, 어두우면 검은색 변환하여
전경(객체)와 배경을 분리.
retval, dst = cv2.threshold(src, thresh, maxval, type[, dst])
- src: 입력 이미지로, 단일 채널 (그레이스케일) 이미지
- thresh: 임계값으로, 이 값을 기준으로 픽셀 값을 분류.
- maxval: 임계값 이상일 때 적용할 값입니다. 보통 255로 설정.
- type: 임계값을 적용하는 방법을 지정하는 플래그. 주요 유형으로는 cv2.THRESH_BINARY, cv2.THRESH_BINARY_INV, cv2.THRESH_TRUNC, cv2.THRESH_TOZERO, cv2.THRESH_TOZERO_INV 등.
- dst: 선택적으로 출력 이미지. 원본 이미지와 동일한 크기와 타입을 가져야 함.
이 함수는 두 개의 반환 값 존재:
- retval: 사용된 임계값.
- dst: 이진화된 결과 이미지.
import cv2
img = cv2.imread("sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
retval, thresholded = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY);
print(retval) # 임계기준값 127.0
cv2.imshow("thresholded", thresholded)
cv2.waitKey(0)
cv2.destroyAllWindows()
적응형 이진화(Adaptive Thresholding) - 조명변화가 심한 환경, 픽셀주변 기준으로 동적 임계값 계산
source는 grayscale , blockSize는 적용영역크기로 홀수로 지정, 마지막값 C 계산된 경계값에서 차감할 값
cv2.adaptiveThreshold(source, maxValue, adaptiveMethod, thresholdType, blockSize, C)
- source = grayscaled image
- maxValue = 임계값
- adaptiveMethod = threshold값을 계산하는 방법( ADAPTIVE_THRESH_MEAN_C = 일반노이즈제거 , ADAPTIVE_THRESH_GAUSSIAN_C = 중심 강조 및 엣지 보존 )
- thresholdType = THRESH_BINARY , THRESH_BINARY_INV
- blockSize = thresholding 적용할 영역 크기, 홀수로 지정, 너무 작으면 노이즈에 민감
- C = 계산된 경계값(평균,가중평균)에서 차감할 값 - 보정용 상수 양수인 경우 작은 전경(객체) 검출 음수일 경우 배경일부도 검출
import cv2
img = cv2.imread("sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
adaptive = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, 11, 2)
cv2.imshow("adaptive", adaptive)
cv2.waitKey(0)
cv2.destroyAllWindows()
블러링(Blurring) - 부드럽게 만들어 노이즈 필터링(제거), 필터사이즈가 클수록 더 흐려짐
dst = cv2.GaussianBlur(source, ksize, sigmaX, dst=None, sigmaY=None, borderType=None)
- source: 입력 영상. 각 채널 별로 처리됨.
- dst: 출력 영상. source와 같은 크기, 같은 타입.
- ksize: 가우시안 커널 크기. (0, 0)을 지정하면 sigma 값에 의해 자동 결정됨
- sigmaX: x방향 sigma.
- sigmaY: y방향 sigma. 0이면 sigmaX와 같게 설정.
- borderType: 가장자리 픽셀 확장 방식.
import cv2
img = cv2.imread("../sample.png")
mean_blur = cv2.blur(img, (5, 5)) #평균 블러링
cv2.imshow("mean_blur", mean_blur)
gaussian_blur = cv2.GaussianBlur(img,(5,5),0) #가우시안 블러링
cv2.imshow("gaussian_blur", gaussian_blur)
median_blur =cv2.medianBlur(img,5)
cv2.imshow("median_blur", median_blur)
bilateral_blur = cv2.bilateralFilter(img, 9, 75, 75) #양방향 블러링 - 자연스럽게 노이즈 제거 경계선 유지
cv2.imshow("bilateral_blur", bilateral_blur)
cv2.waitKey(0)
cv2.destroyAllWindows()
사용자정의 필터 적용 - 이미지의 세부 사항을 강조하거나 경계를 감지하는 등 다양한 이미지 처리 작업에 사용
dst = cv2.filter2D(source, ddepth, kernel, anchor, delta, borderType)
- source: 입력 이미지. numpy 배열로 표현.
- ddepth: 결과 이미지의 깊이(비트 단위). -1로 지정하면 입력 이미지와 동일한 깊이를 사용.
- kernel: 필터링에 사용될 커널. numpy 배열로 정의, 일반적으로 부동소수점 값으로 구성.
- anchor: 선택적으로 커널의 중심을 지정하는 점. 기본값은 (-1, -1)로, 커널의 중심을 사용.
- delta: 필터링된 픽셀에 추가적으로 더해질 값. 기본값은 0.
- borderType: 이미지 가장자리 픽셀을 확장하는 방식을 결정 ( cv2.BORDER_CONSTANT, cv2.BORDER_REFLECT, cv2.BORDER_WRAP 등 )
샤프닝(Sharpening) - 선명하게 만들어 엣지강조, 객체경계를 명확히 함
import cv2
import numpy as np
img = cv2.imread("../sample.png")
cv2.imshow("img", img)
#kernel = np.ones((5,5), np.float32) / 25 #사용자 정의 커널( 평균필터 )
#blurred = cv2.filter2D(img, -1, kernel)
#cv2.imshow("blurred", blurred)
kernel = np.array([[0, -1, 0],
[-1, 5, -1],
[0, -1, 0]])
sharp = cv2.filter2D(img, -1, kernel)
cv2.imshow("sharp", sharp)
cv2.waitKey(0)
cv2.destroyAllWindows()
경계검출(Edge Detection) - 엣지는 이미지에서 밝기 변화가 큰 경계부분을 의미한다고 대표적으로 Sobel, Canny, Laplacian Filter가 있음
Sobel필터 - 미분을 이용 수평/수직으로 미분 연산한다고
import cv2
import numpy as np
img = cv2.imread("../sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
sobelx = cv2.Sobel(gray, cv2.CV_64F, 1, 0, ksize=3)
sobely = cv2.Sobel(gray, cv2.CV_64F, 0, 1, ksize=3)
edge_sobel = cv2.magnitude(sobelx, sobely)
edge_sobel = np.clip(edge_sobel, 0, 255).astype(np.uint8)
cv2.imshow("edge_sobel", edge_sobel)
cv2.waitKey(0)
cv2.destroyAllWindows()
Laplacian필터 - 2차미분 연산, 노이즈에 민감, 더 강한 경계검출 성능
Cany필터 - 노이즈제거, 그라디언트 연산, 비최대억제, 이중 임계값을 활용한 정교한 검출
cv2.Canny(source, threshold1, threshold2[, edges[, apertureSize[, L2gradient]]])
- image: 그레이스케일 이미지
- threshold1: 엣지 검출에서 사용되는 최소 임계값. 이 값보다 낮은 그라디언트 값은 엣지로 간주되지 않음
- threshold2: 엣지 검출에서 사용되는 최대 임계값. 이 값보다 높은 그라디언트 값은 확실한 엣지로 간주됨
- edges: 선택적으로 출력 엣지 이미지
- apertureSize: 선택적으로 소벨 연산자에 사용되는 커널 크기 지정. 기본값은 3
- L2gradient: 선택적으로 그라디언트 크기를 계산할 때 사용할 방법을 지정. 기본값은 False, 그라디언트 크기를 계산할 때 L1 norm을 사용. True로 설정하면 L2 norm을 사용.
threshhold1,2는 1:2 또는 1:3 비율이 적당한 수준이라고
import cv2
img = cv2.imread("../sample.png")
edges = cv2.Canny(img, 100, 200)
cv2.imshow("edges", edges)
cv2.waitKey(0)
cv2.destroyAllWindows()
형태학적 변환(Morphology)
binary나 Grayscale이미지를 Segmentation하여 단순화, 제거, 보정을 통해 형태를 파악한다.
팽창(Dilation), 침식(Erosion) 이 두가지를 조합한 Openinig, Closing이 있음
연산효과용도는 다음과 같다.
| 침식(Erode) | 객체 축소 | 노이즈(작은 객체) 제거 |
| 팽창(Dilate) | 객체 확장 | 끊어진 경계 복원 |
| 열기(Open) | 침식 → 팽창 | 작은 점 제거 |
| 닫기(Close) | 팽창 → 침식 | 구멍 채우기 |
getStructuringElement = 모폴로지 구조 요소(커널) 생성 함수
retval = cv2.getStructuringElement(shape, ksize[, anchor])
- shape : 구조요소모양 ( MORPH_RECT, MORPH_CROSS, MORPH_ELLIPSE )
- ksize : 구조요소크기 (width,height) tuple
- anchor : MORPH_CROSS 구조일때 고정점 좌표
- retval = 0과 1로 구성된 CV_8UC1 타입 행렬 ( 1의 위치가 구조요소모양 결정)
import cv2
img = cv2.imread("../sample.png")
cv2.imshow("img", img)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
eroded = cv2.erode(gray, kernel, iterations=1)
cv2.imshow("eroded", eroded)
dilated = cv2.dilate(gray, kernel, iterations=1)
cv2.imshow("dilated", dilated)
opening = cv2.morphologyEx(gray, cv2.MORPH_OPEN, kernel);
cv2.imshow("opening", opening)
closing = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, kernel);
cv2.imshow("closing", closing)
cv2.waitKey(0)
cv2.destroyAllWindows()
| 그레이스케일 | cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) | 명도 기반 처리 |
| 이진화 | cv2.threshold, cv2.adaptiveThreshold | 밝기 기준 분리 |
| 블러링 | cv2.blur, cv2.GaussianBlur | 노이즈 감소 |
| 샤프닝 | cv2.filter2D | 엣지 강조 |
| 에지 검출 | cv2.Canny | 윤곽선 탐지 |
| 형태학 연산 | cv2.erode, cv2.dilate | 구조 정제 |
| 히스토그램 평활화 | cv2.equalizeHist | 대비 향상 |
도형 윤곽선 검출( Contour ) - 윤곽선은 동일한 밝기나 색상 경계를 따라 연결된 점들의 집합
이진화된 이미지에서 윤곽선을 찾아 구성하는 점들을 반환
contours, hierarchy = cv2.findContours(image, mode, method[, contours[, hierarchy[, offset]]])
- image: 그레이스케일 또는 이진화된 이미지를 사용.
- mode: 윤곽선을 찾는 방법을 지정. cv2.RETR_EXTERNAL, cv2.RETR_LIST, cv2.RETR_TREE 등.
- method: 윤곽선 근사화 방법.
cv2.CHAIN_APPROX_SIMPLE, cv2.CHAIN_APPROX_TC89_L1, cv2.CHAIN_APPROX_TC89_KCOS 등 - contours: 검출된 윤곽선을 저장할 리스트.
- hierarchy: 윤곽선의 계층 구조를 저장할 배열.
- offset: 윤곽선의 좌표를 변환할 때 사용되는 오프셋.
import cv2
img = cv2.imread("../sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #grayscale
_, thresholded = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) #이진화
#윤곽선 찾기
contours, hierarchy = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
#찾은 윤곽선 그리기
cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
import cv2
img = cv2.imread("../sample.png")
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
_, thresholded = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY);
contours, hierarchy = cv2.findContours(thresholded, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
area = cv2.contourArea(contour) #면적
perimeter = cv2.arcLength(contour, True) #둘레
M = cv2.moments(contour) #중심점계산
x, y, w, h = cv2.boundingRect(contour) #직사각형 검출
cv2.rectangle(img, (x, y), (x+w, y+h), (0,255,0), 2)
if M["m00"] != 0:
cx = int(M["m10"] / M["m00"])
cy = int(M["m01"] / M["m00"])
cv2.circle(img, (cx, cy), 5, (255, 0, 0), -1)
print(f"면적={area:.1f}, 둘레={perimeter:.1f}")
#cv2.drawContours(img, contours, -1, (0, 255, 0), 2)
cv2.imshow("img", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
- cv2.arcLength(외곽선좌표, 폐곡선여부) : 외곽선 둘레 길이 반환
- cv2.contourArea(외곽선좌표, 외곽선 진행방향에 따라 부호 있는 면적반환여부 기본 False) : 외곽선으로 구성된 면적반환
- cv2.boundingRect(외곽선좌표) : 외곽선을 외접하여 둘러싸는 가장 작은 사각형 반환
- cv2.approxPolDP(곡선좌표, 근사화정밀도, 폐곡선인식여부) : 외곽선 근사화 반환
- cv2.moments(외곽선좌표) : 윤곽선(Contour)이나 이미지의 면적, 중심 좌표, 방향 등의 기하학적 특성을 쉽게 계산
면적(Area) : M['m00'] 내부픽셀수
공간 모멘트 (Spatial Moments): M['m00'], M['m10'], M['m01'], M['m20'], M['m11'], M['m02'] 등
중심 모멘트 (Central Moments): 질량 중심을 기준으로 계산 (mu20, mu11, mu02 등)
중심점 (Centroid): 질량의 평균 위치 cx = m10/m00, cy = m01/m00
'python' 카테고리의 다른 글
| fastapi framework 기본 실습 (0) | 2026.05.13 |
|---|---|
| pymssql을 사용한 SQL Server 접속 테스트 (0) | 2025.09.24 |
| pip를 통한 package install 등.. (0) | 2025.09.23 |
| python matplot scatter chart , linear regression line exercise (0) | 2021.10.13 |
| python pandas dataframe (0) | 2021.10.12 |