OpenCV-Python 은 두 장의 그림 을 자동 으로 전경 그림 으로 연결 합 니 다.
사진 의 전경 연결 은 이제 더 이상 신기 하지 않다.현재 의 스마트 카메라 와 휴대 전화 카 메 라 는 기본적으로 사진 자동 전경 연결 기능 을 가지 고 있 지만 일반적으로 촬영 자 에 게 설비 의 안정 과 단 방향의 이동 촬영 을 유지 하여 비교적 좋 은 연결 결 과 를 실현 하도록 요구한다.이 는 맞 춤 형 그림 사이 에 맞 춤 형 결과 의 정확성 과 완전 성 을 확보 하기 위해 비슷 한 구역 이 있어 야 하기 때문이다.본 고 는 주로 Python 과 OpenCV 라 이브 러 리 로 두 장의 그림 의 자동 조합 을 어떻게 실현 하 는 지 간단하게 설명 하고 먼저 두 장의 그림 조합 원 리 를 간단하게 소개 한다.
기본 원리
두 장의 그림 의 간단 한 조합 을 실현 하려 면 두 장의 그림 에서 비슷 한 점(적어도 네 개,homography 매트릭스 의 계산 은 최소 네 개의 점 이 필요 하기 때 문)을 찾 아야 한다.한 장의 그림 을 계산 하면 다른 그림 의 변환 행렬(homography 단일 응력 행렬)로 바 꿀 수 있다.이 행렬 로 그 그림 을 바 꾼 후 다른 그림 에 해당 하 는 위치 에 놓 습 니 다.이렇게 하면 간단 한 전경 조합 을 실현 할 수 있다.물론 맞 추 면 그림 이 겹 치기 때문에 그림 중첩 부분의 픽 셀 값 을 다시 계산 해 야 한다.그렇지 않 으 면 결과 가 보기 흉 할 것 이다.그래서 정리 해 보면 두 가지 절차 가 있 습 니 다.
1.두 장의 그림 에서 비슷 한 점 을 찾 아 행렬 을 계산한다.
2.한 장의 그림 을 다른 그림 의 적당 한 위치 로 바 꾸 고 중첩 구역 의 새로운 픽 셀 값 을 계산 합 니 다.(여기 가 바로 그림 융합 에 필요 한 전략 입 니 다)
구체 적 실현
유사 점 을 찾다
물론 비슷 한 점 을 수 동 으로 찾 을 수 있 지만 귀 찮 습 니 다.유사 점 이 많 거나 유사 점 에 대응 하 는 위치 가 정확 할 수록 얻 는 결과 가 좋 지만 사람의 육안 으로 찾 는 위 치 는 항상 오차 가 있 고 많은 점 을 찾 는 것 도 쉬 운 일이 아니다.그래서 똑똑 한 사람 이 유사 점 을 자동 으로 찾 는 알고리즘 을 설계 했다.여기 서 우 리 는 SIFT 알고리즘 을 사 용 했 고 OpenCV 도 우리 에 게 SIFT 알고리즘 의 인 터 페 이 스 를 제공 하기 때문에 우 리 는 스스로 힘 들 게 실현 할 필요 가 없다.다음은 두 장의 테스트 그림 의 원 도와 유사 점 을 찾 은 그림 이다.
그 중에서 빨간색 점 은 SIFT 알고리즘 이 찾 아 낸 유사 점 이 고 녹색 선 은 모든 비슷 한 점 에서 찾 아 낸 신뢰 도가 높 은 유사 점 을 나타 낸다.알고리즘 이 찾 아 낸 유사 점 이 꼭 100%정확 한 것 은 아니 기 때문이다.그 다음 에 이런 선별 한 유사 점 에 따라 행렬 을 바 꿀 수 있다.물론 OpenCV 도 해당 하 는 인 터 페 이 스 를 제공 하여 우리 의 계산 을 편리 하 게 하고 구체 적 인 코드 실현 도 OpenCV 의 Python tutorial 에서 찾 을 수 있다[1]
사진 조합
변환 행렬 을 계산 한 다음 두 번 째 단 계 는 계 산 된 변환 행렬 로 그 중의 한 장의 그림 을 변환 한 다음 에 변 경 된 그림 을 다른 그림 과 겹 쳐 중첩 구역 의 새로운 픽 셀 값 을 다시 계산한다.중첩 구역 의 픽 셀 값 을 계산 하 는 데 있어 서 사실 여러 가지 방법 으로 좋 은 융합 효 과 를 실현 할 수 있 습 니 다.여 기 는 가장 간단 하고 거 칠 지만 효과 도 좋 은 방식 을 사용 합 니 다.솔직히 말 하면 한 이미지 의 선형 그 라 데 이 션 을 실현 하 는 것 이다.겹 치 는 구역 에 대해 왼쪽 부분 에 가 깝 고 왼쪽 이미지 내용 을 많이 표시 하 며 오른쪽 부분 에 가 까 워 서 오른쪽 이미지 의 내용 을 많이 표시 하 는 것 이다.공식 적 으로 알파 가 픽 셀 점 가로 좌표 에서 좌우 중첩 구역 경계 가로 좌표 의 거 리 를 나타 낸다 고 가정 하면 새로운 픽 셀 값 은 new pixel=왼쪽 픽 셀 값 이다.× (1-알파)+오른쪽 픽 셀 값× alpha 。이렇게 하면 간단 한 융합 효 과 를 실현 할 수 있다.더 복잡 하거나 더 좋 은 효 과 를 실현 하려 면 multi-band 융합 을 검색 하고 시도 해 볼 수 있다.여 기 는 군더더기 에 불과 하 다.마지막 으로 실 현 된 결과 와 코드 를 동봉 하 니 참고 하 시기 바 랍 니 다.
Python 코드 는 다음 과 같 습 니 다:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
if __name__ == '__main__':
top, bot, left, right = 100, 100, 0, 500
img1 = cv.imread('test1.jpg')
img2 = cv.imread('test2.jpg')
srcImg = cv.copyMakeBorder(img1, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0))
testImg = cv.copyMakeBorder(img2, top, bot, left, right, cv.BORDER_CONSTANT, value=(0, 0, 0))
img1gray = cv.cvtColor(srcImg, cv.COLOR_BGR2GRAY)
img2gray = cv.cvtColor(testImg, cv.COLOR_BGR2GRAY)
sift = cv.xfeatures2d_SIFT().create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1gray, None)
kp2, des2 = sift.detectAndCompute(img2gray, None)
# FLANN parameters
FLANN_INDEX_KDTREE = 1
index_params = dict(algorithm=FLANN_INDEX_KDTREE, trees=5)
search_params = dict(checks=50)
flann = cv.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1, des2, k=2)
# Need to draw only good matches, so create a mask
matchesMask = [[0, 0] for i in range(len(matches))]
good = []
pts1 = []
pts2 = []
# ratio test as per Lowe's paper
for i, (m, n) in enumerate(matches):
if m.distance < 0.7*n.distance:
good.append(m)
pts2.append(kp2[m.trainIdx].pt)
pts1.append(kp1[m.queryIdx].pt)
matchesMask[i] = [1, 0]
draw_params = dict(matchColor=(0, 255, 0),
singlePointColor=(255, 0, 0),
matchesMask=matchesMask,
flags=0)
img3 = cv.drawMatchesKnn(img1gray, kp1, img2gray, kp2, matches, None, **draw_params)
plt.imshow(img3, ), plt.show()
rows, cols = srcImg.shape[:2]
MIN_MATCH_COUNT = 10
if len(good) > MIN_MATCH_COUNT:
src_pts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dst_pts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
M, mask = cv.findHomography(src_pts, dst_pts, cv.RANSAC, 5.0)
warpImg = cv.warpPerspective(testImg, np.array(M), (testImg.shape[1], testImg.shape[0]), flags=cv.WARP_INVERSE_MAP)
for col in range(0, cols):
if srcImg[:, col].any() and warpImg[:, col].any():
left = col
break
for col in range(cols-1, 0, -1):
if srcImg[:, col].any() and warpImg[:, col].any():
right = col
break
res = np.zeros([rows, cols, 3], np.uint8)
for row in range(0, rows):
for col in range(0, cols):
if not srcImg[row, col].any():
res[row, col] = warpImg[row, col]
elif not warpImg[row, col].any():
res[row, col] = srcImg[row, col]
else:
srcImgLen = float(abs(col - left))
testImgLen = float(abs(col - right))
alpha = srcImgLen / (srcImgLen + testImgLen)
res[row, col] = np.clip(srcImg[row, col] * (1-alpha) + warpImg[row, col] * alpha, 0, 255)
# opencv is bgr, matplotlib is rgb
res = cv.cvtColor(res, cv.COLOR_BGR2RGB)
# show the result
plt.figure()
plt.imshow(res)
plt.show()
else:
print("Not enough matches are found - {}/{}".format(len(good), MIN_MATCH_COUNT))
matchesMask = None
Reference[1] OpenCV tutorial: https://docs.opencv.org/3.4.1/d1/de0/tutorial_py_feature_homography.html
OpenCV-Python 이 두 장의 그림 을 자동 으로 전경 그림 으로 연결 하 는 것 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 관련 OpenCV 그림 이 자동 으로 전경 그림 으로 연결 되 는 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 부 탁 드 리 겠 습 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Visual Studio 2017에서 OpenCV 템플릿 프로젝트 만들기・Windows 7 Professional 64bit ・Visual Studio 2017 Version 15.9.14 · OpenCV 3.4.1 OpenCV의 도입 방법 등은 아래를 참조하십시오. Visual Stu...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.