ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 야경 사진 노이즈 제거
    영상처리/3D computer vision 2024. 2. 22. 23:26
    728x90

    야경 사진을 여러장 찍어서 denoising하는 코드를 만들었다.

    1. 먼저 여러장의 사진을 최대한 같은 위치에서 찍었다.

     

    최대한 제자리에서 찍었으나 흔들림은 어쩔 수 없다.

    2. ORB feature를 이용, 영상간 homography 변환을 추출, warping을 수행한다.

    homography를 이용, warping하면 영상간 registration이 가능. 근거리나 moving object 처리는 불가하지만, 야경의 원거리 scene에는 잘 동작한다.

     

    3. warping 된 영상을 유사도 기반으로 weight를 주어 합친다.

     

    import torch
    import cv2
    import numpy as np
    import os
    
    In [ ]:
    ref_img=cv2.imread('20240222_190925.jpg')
    
    h=ref_img.shape[0]
    w=ref_img.shape[1]
    
    In [ ]:
    orb = cv2.ORB_create()
    bf = cv2.BFMatcher(cv2.NORM_HAMMING, crossCheck=True)
    
    In [ ]:
    flist=os.listdir('./')
    flist=[a for a in flist if a[-4:]=='.jpg']
    # os.mkdir('result')
    warped_img_list=[]
    for fname in flist:
        new_img=cv2.imread(fname)
        kp1, des1 = orb.detectAndCompute(ref_img,None)
        kp2, des2 = orb.detectAndCompute(new_img,None)
        matches = bf.match(des1,des2)
    
    
        dst_pts = np.float32([ kp1[m.queryIdx].pt for m in matches[:50] ]).reshape(-1,1,2)
        src_pts = np.float32([ kp2[m.trainIdx].pt for m in matches[:50] ]).reshape(-1,1,2)
        H, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
    
        # print(H)
    
        warped=cv2.warpPerspective(new_img,H,(w,h))
        cv2.imwrite('result/'+fname,warped)
        warped_img_list+=[np.copy(warped)]
    
    In [ ]:
    def weight_calc(ref_img,new_img):
        ref_img = ref_img.astype(np.float32)
        new_img = new_img.astype(np.float32)
        weight=np.sqrt(np.max(np.sqrt(ref_img)/(np.abs(ref_img-new_img)+1),axis=2))
        return weight
    
    In [ ]:
    result= np.copy(ref_img).astype(np.float32)
    weight_sum = np.ones((h,w))
    for img in warped_img_list:
        weight=weight_calc(ref_img,img)
        for i in range(3):
            result[:,:,i] += weight*img[:,:,i].astype(np.float32)
        weight_sum+=weight
    
    for i in range(3):
        result[:,:,i]/=weight_sum
    
    In [ ]:
    cv2.imwrite('result/merged.jpg',result)
    
    Out[ ]:
     

    input으로 사용한 reference image이다.
    Merge된 결과물이다.

    확대하지 않았을때는 비슷해보이지만, 확대해보면 아래와 같이 noise가 크게 감소된것을 볼 수 있다.

     

    다섯장이나 찍는 수고로움이 있었으나, 보통 야경사진이 손떨림에 의해 엉망이 되는걸 고려하면, 여러장으로 나누어찍어서 적절히 합치는게 훨씬 효율적임을 알 수 있다.

    728x90
Designed by Tistory.