- 1. 비트 연산 및 마스킹
- 2. 컨볼 루션 및 블러 링
- 3. 선명하게-이미지 흐림 반전
- 4. 탈곡 (Binarization)
- 5. 팽창, 침식, 개방 / 폐쇄
- 6. 가장자리 감지 및 이미지 그라디언트
- 14. 관점 및 아핀 변환
- 8. 라이브 스케치 애플리케이션
이전 튜토리얼에서 우리는 OpenCV에 대해 배웠고 몇 가지 기본 이미지 처리를 수행 한 다음 다음 튜토리얼에서는 자르기, 회전, 이미지 변환 등과 같은 OpenCV에서 이미지 조작을 수행했습니다. 따라서 이전 이미지 조작 튜토리얼을 계속 진행하면서 여기에서 학습합니다. 튜토리얼의 끝 에서 웹캠 라이브 피드에서 라이브 스케치를 만들기 위해 python-opencv 프로그램을 빌드 할 것 입니다. 이 응용 프로그램은 지금까지 배웠거나이 튜토리얼에서 배울 많은 이미지 처리 기능을 사용하므로 모든 기능을 다루는 좋은 실용적인 예가 될 것입니다.
이전 튜토리얼에서 언급 했듯이 OpenCV는 C ++, Python 및 Java 인터페이스가 있고 Windows, Linux, Mac OS, iOS 및 Android를 지원하는 오픈 소스 Commuter Vision Library 입니다. 따라서 Python 및 Linux 환경에서 Raspberry Pi에 쉽게 설치할 수 있습니다. 또한 OpenCV 및 연결된 카메라가있는 Raspberry Pi를 사용하여 얼굴 감지, 얼굴 잠금, 개체 추적, 자동차 번호판 감지, 홈 보안 시스템 등과 같은 많은 실시간 이미지 처리 애플리케이션을 만들 수 있습니다.
이 튜토리얼에서는 Python OpenCV를 사용하여 더 많은 이미지 조작 을 볼 것 입니다. 여기에서는 Python OpenCV를 사용하여 이미지에 다음 함수를 적용하는 방법을 배웁니다.
- 비트 연산 및 마스킹
- 컨볼 루션 및 블러 링
- 선명하게-이미지 흐림 반전
- 임계 값 (Binarization)
- 팽창, 침식, 개방 / 폐쇄
- 가장자리 감지 및 이미지 그라디언트
- 관점 및 Affine 변환
- 라이브 스케치 애플리케이션
1. 비트 연산 및 마스킹
비트 연산은 이미지 마스킹에 도움이되고 간단한 이미지를 만드는 데 도움이됩니다.
사각형 만들기
import cv2 import numpy as np # 이것은 회색조 이미지이기 때문에 2 차원 만 사용합니다. #colored 이미지를 사용하는 경우에는 rectangle = np.zeros ((300,300,3), np.uint8) # 사각형 사각형 만들기 = np.zeros ((300,300), np.uint8) cv2.rectangle (square, (50,50), (250,250), 255, -1) cv2.imshow ("square", square) cv2 . waitKey (0)
타원 만들기
ellipse = np.zeros ((300,300), np.uint8) cv2.ellipse (ellipse, (150,150), (150,150), 30,0,180,255, -1) cv2.imshow ("ellipse", ellipse) cv2.waitKey (0)
비트 연산 실험
#AND_ 둘이 교차하는 위치 만 표시
비트 AND = cv2.bitwise_and (square, ellipse) cv2.imshow ("AND", BitwiseAND) cv2.waitKey (0)
#OR_ 정사각형 또는 타원이있는 위치 만 표시
BitwiseOR = cv2.bitwise_or (square, ellipse) cv2.imshow ("OR", BitwiseOR) cv2.waitKey (0)
#XOR_ 둘 중 하나만 존재하는 경우에만 표시
BitwiseXOR = cv2.bitwise_xor (square, ellipse) cv2.imshow ("XOR", BitwiseXOR) cv2.waitKey (0)
#NOT_은 타원의 일부가 아닌 모든 것을 보여 주며 NOT 연산은 단일 도형에만 적용 할 수 있습니다.
BitwiseNOT_elp = cv2.bitwise_not (ellipse) cv2.imshow ("NOT_ellipse", BitwiseNOT_elp) cv2.waitKey (0) cv2.destroyAllWindows ()
2. 컨볼 루션 및 블러 링
컨벌루션은 일반적으로 원본 함수의 수정 된 버전 인 제 3 함수를 생성하는 두 가지 기능을 수행되는 수학적 연산이다.
출력 이미지 = 이미지 함수 커널 크기
에서 컴퓨터 비전 우리는 커널은 우리가 우리의 이미지 위에 우리의 조작 기능을 실행하는 동안 크기를 지정할 수있어 사용합니다.
Blurring 은 영역 (Kernel) 내의 픽셀을 평균하는 작업입니다.
OpenCV는 커널을 적용하여 이미지를 흐리게 처리하고, 커널은 최종 이미지를 생성하기 위해 커널이 이미지의 모든 픽셀에 하나씩 적용되는 이웃 픽셀의 다른 양과 결합하여 주어진 픽셀의 값을 변경하는 방법을 알려줍니다.
간단히 말해서, 이미지 컨볼 루션은 단순히 두 행렬의 요소 현명한 곱셈과 합입니다.
다음 예제를 통해 간단히 이해할 수 있습니다.
위는 3X3 커널입니다.
우리는 1/25를 곱하여 정규화합니다. 즉, 합을 1로 만듭니다. 이미지를 밝게하거나 어둡게하는 경우처럼 강도를 높이거나 낮추었습니다.
cv2.filter2D (이미지, -1, 커널) 함수로 주어진 opencv 블러 링 메서드 filter2D를 테스트 해 봅시다.
import cv2 import numpy as np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
# 3x3 커널 매트릭스 만들기
kernel_3x3 = np.ones ((3,3), np.float32) / 9
# cv2.filter2D를 사용하여 커널을 이미지와 결합합니다.
blur = cv2.filter2D (image, -1, kernel_3x3) cv2.imshow ('3x3_blurring', blur) cv2.waitKey (0)
# 7x7 커널 매트릭스 만들기
kernel_7x7 = np.ones ((7,7), np.float32) / 49
# cv2.filter2D를 사용하여 커널을 이미지와 결합합니다.
blur = cv2.filter2D (image, -1, kernel_7x7) cv2.imshow ('7x7_blurring', bluring) cv2.waitKey (0) cv2.destroyAllWindows ()
있다 방법을 흐리게 다른 종류의 도는:
cv2.blur – 지정된 창에 대한 평균 값입니다.
cv2.GaussianBlur – 비슷하지만 가우시안 창을 사용합니다 (중심 주변의 점이 더 강조됨).
cv2.medianBlur – 창에있는 모든 요소의 중앙값을 사용합니다.
cv2.bilateralFilter – 가장자리를 선명하게 유지하면서 흐리게 처리하고 가장자리와 선 세부 사항을 유지합니다.
아래 코드를 사용하여 원본 이미지를 먼저 표시합니다.
import cv2 import numpy as np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
cv2.blur:
이 방법에서 평균화는 정규화 된 상자 필터를 사용하여 이미지를 컨 볼빙하여 수행되며, 이는 상자 아래에서 발생하고 중앙 요소를 대체합니다. 여기서 상자 크기는 홀수이고 양수 여야 합니다.
# cv2.blur blur = cv2.blur (image, (3,3)) cv2.imshow ('Averaging', blur) cv2.waitKey (0)
cv2.GaussianBlur:
# cv2.GaussianBlur # 박스 필터 대신 Gaussian kernel Gaussian = cv2.GaussianBlur (image, (7,7), 0) cv2.imshow ('Gaussian blurring', Gaussian) cv2.waitKey (0)
cv2.medianBlur:
커널 영역 아래의 모든 픽셀의 중앙값을 취하고 중앙 요소는이 중앙값으로 대체됩니다.
# cv2.medianBlur # 커널 영역 아래의 모든 픽셀의 중앙값을 취하고 중앙 요소 #는이 중앙값으로 대체됩니다. 중앙값 = cv2.medianBlur (이미지 5) cv2.imshow ('중간 번짐', 중앙값) cv2.waitKey (0)
cv2.bilateralFilter:
양측은 가장자리를 날카롭게 유지하면서 소음 제거에 매우 효과적입니다.
# cv2.bilateralFilter #Bilateral은 가장자리를 선명하게 유지하면서 노이즈 제거에 매우 효과적입니다. bilateral = cv2.bilateralFilter (image, 9,75,75) cv2.imshow ('bilateral blurring', bilateral) cv2.waitKey (0) cv2 . destroyAllWindows ()
이미지 노이즈 제거 비 로컬은 노이즈 제거를 의미합니다.
import cv2 import numpy as np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
#None 이후의 매개 변수는 필터 강도 'h'(5-10은 좋은 범위) #next는 색상 구성 요소의 경우 h, 다시 h 와 동일한 값으로 설정 됩니다.
dst = cv2.fastNlMeansDenoisingColored (image, None, 6,6,7,21) cv2.imshow ('Fast는 denois를 의미합니다', dst) cv2.waitKey (0) cv2.destroyAllWindows ()
non-local 평균 노이즈 제거에는 4 가지 변형이 있습니다.
cv2.fastNlMeansDenoising () – 단일 회색조 이미지 용
cv2.fastNlMeansDenoisingColored () – 단색 이미지
cv2.fastNlmeansDenoisingMulti () – 이미지 시퀀스 회색 조용
cv2.fastNlmeansDenoisingcoloredMulti () – 컬러 이미지 시퀀스 용
3. 선명하게-이미지 흐림 반전
선명하게하기는 블러 링의 반대이며 이미지의 가장자리를 강조하거나 강조합니다.
커널 =,,
우리의 커널 행렬은 1까지 합산되므로 정규화 할 필요가 없습니다 (즉, 원래의 밝기와 동일한 밝기로 계수를 곱함). 커널이 1로 정규화되지 않으면 이미지가 더 밝거나 어두워집니다.
import cv2 import numpy as np image = cv2.imread ('elephant.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
kernel_sharpening = np.array (,
])
# 입력 이미지에 선명 화 커널 적용
sharpened = cv2.filter2D (image, -1, kernel_sharpening) cv2.imshow ('sharpened image', sharpened) cv2.waitKey (0) cv2.destroyAllWindows ()
4. 탈곡 (Binarization)
임계 값은 이미지를 이진 형식으로 변환하는 행위입니다. opencv에는 다음과 같이 정의 된 임계 값에 대한 별도의 기능이 있습니다.
Cv2.threshold (이미지, 임계 값, 최대 값, 임계 값 유형)
다음 임계 값 유형이 있습니다.
- cv2.THRESH_BINARY – 가장 일반적
- cv2. THRESH_BINARY_INV – 가장 일반적
- cv2.THRESH_TRUNC
- cv2.THRESH_TOZERO
- cv2. THRESH_TOZERO_INV
참고: 임계 값을 설정하기 전에 이미지를 그레이 스케일로 변환해야합니다.
import cv2 import numpy as np #load image as grayscale image = cv2.imread ('gradient.jpg', 0) cv2.imshow ('original', image) cv2.waitKey (0)
# 127보다 작은 값은 0 (검은 색)으로, 127보다 큰 값은 255 (흰색)로 이동
_, thresh1 = cv2.threshold (image, 127,255, cv2.THRESH_BINARY) cv2.imshow ('1 threshold', thresh1) cv2.waitKey (0)
# 127 미만의 값은 255로 이동하고 127 이상의 값은 0으로 이동 (위의 반대)
_, thresh2 = cv2.threshold (image, 127,255, cv2.THRESH_BINARY_INV) cv2.imshow ('2 threshold', thresh2) cv2.waitKey (0)
# 127 이상의 값은 127에서 잘리고 (보유) 255 인수는 사용되지 않습니다.
_, thresh3 = cv2.threshold (image, 127,255, cv2.THRESH_TRUNC) cv2.imshow ('3 thresh trunc', thresh3) cv2.waitKey (0)
# 127보다 작은 값은 0이되고 127보다 큰 값은 변경되지 않습니다.
_, thresh4 = cv2.threshold (image, 127,255, cv2.THRESH_TOZERO) cv2.imshow ('4 threshold', thresh4) cv2.waitKey (0)
# 위의 Revesrse, 127 미만은 변경되지 않고, 127 이상은 0이됩니다.
_, thresh5 = cv2.threshold (image, 127,255, cv2.THRESH_TOZERO_INV) cv2.imshow ('5 threshold', thresh5) cv2.waitKey (0) cv2.destroyAllWindows ()
5. 팽창, 침식, 개방 / 폐쇄
이것은 수학적 형태학 분야의 연산입니다.
Dilation – 이미지의 개체 경계에 픽셀을 추가합니다.
Erosion – 이미지의 개체 경계에서 픽셀을 제거합니다.
개방 – 침식 후 팽창.
폐쇄 – 팽창 후 침식.
열림은 먼저 이미지를 침식 (노이즈 제거)으로 얇게 만든 다음 확장하므로 이미지 노이즈 제거에 매우 유용합니다.
팽창 및 침식과의 혼동
opencv는 흰색 배경을 원본 그림 대신 확장 또는 침식되는 이미지로 간주하기 때문에 일반적으로 흰색 배경이있는 그림에서 팽창과 침식 사이에 혼동이 발생합니다. 아래에 표시됩니다.
기억 팽창 시킴이 동시에 이미지에서 객체의 경계 픽셀을 추가 침식 이미지에서 객체의 경계에서의 픽셀을 제거
import cv2 import numpy as np image = cv2.imread ('imagecv.png', 0) cv2.imshow ('original', image) cv2.waitKey (0)
#Erosion
# 커널 크기를 정의합시다
커널 = np.ones ((5,5), np.uint8)
# 이제 이미지를 침식합니다. 여기서 반복은 이미지를 침식하려는 횟수가 아닙니다.
erosion = cv2.erode (image, kernel, iterations = 1) cv2.imshow ('Erosion', erosion) cv2.waitKey (0)
#팽창
dilation = cv2.dilate (image, kernel, iterations = 1) cv2.imshow ('dilation', dilation) cv2.waitKey (0)
#opening, 소음 제거에 좋음
열기 = cv2.morphologyEx (image, cv2.MORPH_OPEN, kernel) cv2.imshow ('opening', opening) cv2.waitKey (0)
#closing, 노이즈 제거에 좋음
close = cv2.morphologyEx (image, cv2.MORPH_CLOSE, kernel) cv2.imshow ('closing', closing) cv2.waitKey (0) cv2.destroyAllWindows ()
6. 가장자리 감지 및 이미지 그라디언트
가장자리 감지는 특히 윤곽을 다룰 때 컴퓨터 비전에서 매우 중요한 영역입니다.
가장자리는 이미지의 경계로 정의 할 수 있으며 실제로 이미지에 대한 많은 정보를 보존하는 이미지에서 개체를 정의하는 가장자리입니다.
공식적으로 Edge 는 이미지의 갑작스러운 변화 (불연속성)로 정의 할 수 있으며 픽셀만큼 많은 정보를 인코딩 할 수 있습니다.
위의 이미지는 컴퓨터 비전이 이미지를 식별하고 인식하는 방법을 보여줍니다.
가장자리 감지 알고리즘:-가장자리 감지 알고리즘 에는 세 가지 주요 유형이 있습니다.
- Sobel – 수직 또는 수평 이미지를 강조합니다.
- Laplacian – 낮은 오류율, 잘 정의 된 가장자리 및 정확한 감지로 인해 최적입니다.
- Canny Edge 감지 알고리즘 (1986 년 john.F. Canny에 의해 상 속됨)
1. 가우시안 블러 적용
2. 이미지의 강도 기울기를 찾습니다.
3. 비 최대 억제를 적용합니다 (즉, 가장자리가 아닌 픽셀 제거).
4. 히스테리시스는 임계 값을 적용합니다 (즉, 픽셀이 상한 및 하한 임계 값 내에있는 경우 에지로 간주 됨).
import cv2 import numpy as np image = cv2.imread ('input.jpg', 0) height, width = image.shape
# 소벨
# 소벨 가장자리 추출
sobel_x = cv2.Sobel (image, cv2.CV_64F, 0,1, ksize = 5) sobel_y = cv2.Sobel (image, cv2.CV_64F, 1,0, ksize = 5) cv2.imshow ('original', image) cv2.waitKey (0) cv2.imshow ('sobelx', sobel_x) cv2.waitKey (0)
# 소비
cv2.imshow ('sobely', sobel_y) cv2.waitKey (0)
sobel_OR = cv2.bitwise_or (sobel_x, sobel_y) cv2.imshow ('sobelOR', sobel_OR) cv2.waitKey (0)
# 라 플라이 안
laplacian = cv2.Laplacian (image, cv2.CV_64F) cv2.imshow ('Laplacian', laplacian) cv2.waitKey (0)
#canny 가장자리 감지 알고리즘은 기울기 값을 임계 값으로 사용합니다. #canny에서는
threshold1과 threshold2의 두 가지 값을 제공해야합니다.
# 임계 값 2보다 큰 모든 그라디언트는 가장자리로 간주됩니다.
# 임계 값 1보다 큰 그라디언트는 가장자리가 아닌 것으로 간주됩니다.
임계 값 1과 임계 값 2 사이 #values 에지 비 에지로하거나있는
자신이 강도에서 연결되는 방식 #on 경우 60 이하의 값이 되는 것으로 간주
가장자리 #non wheareas (120) 위의 모든 에지 값이 고려된다.
canny = cv2.Canny (image, 60,120) cv2.imshow ('canny', canny ) cv2.waitKey (0) cv2.destroyAllWindows ()
14. 관점 및 아핀 변환
한 걸음 뒤로 물러나서 affine 및 non-affine 변환을 살펴 보겠습니다. 아래 표시된 원본 이미지는 가장자리가 어느 시점에서 만나게 될 것이기 때문에 분명히 non affine 이미지입니다. 변환.
이 원근 변환을 위해서는 원본 이미지의 네 좌표와 출력 이미지의 네 점이 필요합니다. 이들은 points_A 및 points_B로 표시됩니다. 먼저 이러한 포인트의 도움으로 getPerspectiveTransform 함수 의 도움으로 변환 행렬 M을 계산 합니다.
그런 다음이 행렬은 최종 출력을 생성 하기 위해 warpPerspective 함수에 제공됩니다.
이제 먼저 Perspective 변환을 시도해 보겠습니다.
import cv2 import numpy as np import matplotlib.pyplot as plt image = cv2.imread ('paper.jpg') cv2.imshow ('original', image) cv2.waitKey (0)
# 원본 이미지의 4 개 모서리 좌표
points_A = np.float32 (,,,])
# 원하는 출력물의 4 개 모서리
좌표 # A4 용지 비율 1: 1.41 사용
points_B = np.float32 (,,,])
# 두 점의 두 세트를 사용하여 전향 적 변환 행렬 을 계산합니다.
M = cv2.getPerspectiveTransform (points_A, points_B) warped = cv2.warpPerspective (image, M, (420,594)) cv2.imshow ('warpprespective', warped) cv2.waitKey (0) cv2.destroyAllWindows ()
변환을 얻으려면 세 점만 필요하므로 Affine 변환이 non-affine 변환보다 쉽습니다. 전체 프로세스는 동일하지만 원근 변환 대신 이제 affine 변환이 있으며 수동으로 입력하는 대신 shape 함수 에서 warpAffine의 열과 행을 정의 합니다.
import cv2 import numpy as np import matplotlib.pyplot as plt image = cv2.imread ('box.jpg') rows, cols = image.shape cv2.imshow ('original', image) cv2.waitKey (0)
# 원본 이미지의 3 개 모서리 좌표
points_A = np.float32 (,,])
# 원하는 출력의 3 개 모서리
좌표 # A4 용지 1: 1.41 비율 사용
points_B = np.float32 (,,])
# 두 점의 두 세트를 사용하여 Affine #transformation matrix, M 을 계산합니다.
M = cv2.getAffineTransform (points_A, points_B) warped = cv2.warpAffine (image, M, (cols, rows)) cv2.imshow ('warpaffine', warped) cv2.waitKey (0) cv2.destroyAllWindows ()
8. 라이브 스케치 애플리케이션
먼저, 위의 모든 이미지 조작 기능을 읽은 후이 미니 프로젝트를 구성한 것을 축하합니다. 그래서이 Python OpenCV의 미니 프로젝트에서 우리는 루프와 함수의 새로운 개념을 배울 것입니다. 프로그래밍에 익숙하다면 함수와 루프가 무엇인지 더 폭넓게 이해하고 있어야합니다. 그러나 파이썬에서 루프와 함수의 기본 개념은 동일하게 유지되지만이를 정의하는 방법은 약간 변경됩니다.
따라서이 프로그램을 시작할 때“ def sketch (image): ” 아래에있는 특정 명령문 그룹을 볼 수 있습니다 . 이것은 특정 출력을 위해 함께 작동하는 명령문 그룹의 함수에 대한 공식적인 정의입니다.
따라서이 스케치 는 함수입니다. 파이썬에서 함수는 "def"로 정의되고 ":"표시로 끝납니다. 또한 함수 내부에 있어야하거나 함수가 제대로 작동하는 데 필요한 문은 함수에 의해 자동으로 정렬됩니다. 따라서 함수에서 나오려면 문을 완전히 왼쪽으로 정렬해야했습니다. 추가 참조는 python에서 함수가 정의되는 방법에 대한 google을 참조 할 수 있습니다.
따라서이 스케치 기능에서 우리는 함께 결합하여 출력을 제공하는 여러 레이어의 이미지 처리를 도입했습니다. 먼저 이미지를 그레이 스케일로 변환 하여 opencv가 쉽게 처리 할 수 있도록 한 다음 그레이 스케일 이미지에 가우시안 블러를 적용 하여 노이즈를 줄입니다. 그런 다음 가장자리는 canny의 가장자리 감지 알고리즘의 도움 으로 추출되고 가장자리 정의 이미지에 이진 역이 적용됩니다. 여기서 이진 역은 bitwise_NOT에 의해 수행 될 수도 있지만 자유를 제공하기 때문에이 임계 값 이진 역을 의도적으로 선택했습니다. 명확한 이미지를 얻을 때까지 매개 변수를 설정합니다.
또한이 함수는 인수 이미지를 취하고 두 개의 인수 ret 및 mask를 반환합니다. ret은 함수가 성공적으로 실행되었는지 여부를 알려주는 부울이고 마스크는 함수의 최종 출력, 즉 처리 된 이미지입니다.
이어서 제 OpenCV의 개념에서 동작 웹캠이다 수행된다 cv2.VideoCapture (0) 물체의 이미지 저장 기능, 모자 캡으로 읽을 수 cap.read () 참고도 여기 기능을 캡. read ()는 계속해서 이미지를 캡처해야했기 때문에 무한 while 루프 내에 있습니다. 라이브 비디오의 느낌을주기 위해 비디오의 프레임 속도는 대부분 24에서 60 사이 인 웹캠의 프레임 속도입니다. fps.
cap.read () 는 ret 및 frame을 반환합니다. 여기서 ret은 함수가 성공적으로 실행되었는지 여부를 나타내는 부울이며 프레임에 웹캠에서 찍은 이미지가 포함되어 있습니다.
아래는 라이브 스케치를 실행하기위한 완전한 Python OpenCV 코드입니다.
import cv2 import numpy as np #sketch 생성 함수 def sketch (image): # 이미지를 회색조로 변환 img_gray = cv2.cvtColor (image, cv2.COLOR_BGR2GRAY) # 가우스 블러를 사용하여 이미지 정리 img_gray_blur = cv2.GaussianBlur (img_gray, (5,5), 0) #extract edge canny_edges = cv2.Canny (img_gray_blur, 10,70) # 이미지 반전 바이너리 화 ret, mask = cv2.threshold (canny_edges, 70,255, cv2.THRESH_BINARY_INV) return mask #initialize webcam, cap 은 비디오 캡처에서 제공하는 객체입니다. # 성공 여부를 나타내는 부울을 포함합니다 (ret). # 웹캠 (frame) cap = cv2.VideoCapture (0) 에서 수집 한 이미지도 포함하고 True: ret, frame = cap.read () cv2.imshow ('livesketcher', sketch (frame)) if cv2.waitKey (1) == 13: # 13은 엔터 키 중단 # 카메라 해제 및 창 닫기 cap.release () cap.release () cv2.destroyAllWindows () 의 도움으로 웹캠을 해제하는 것을 잊지 마십시오.
이것이 Python-OpenCV의 이미지 조작 파트 2의 끝입니다. 컴퓨터 비전과 OpenCV를 잘 이해하려면 이전 기사 (Python OpenCV 및 이미지 조작 시작하기 (Python OpenCV) (Part 1))를 살펴보면 Computer Vision으로 멋진 것을 만들 수 있습니다.