Flat Field 이미지 처리

14264 단어 파이썬OpenCV

소개



현미경 사진에서 입자 등을 자동 카운트시킬 때, 원래의 화상의 명도에 편차가 있으면 임계값의 설정이 어려워집니다.
그래서, 미리 배경의 명도의 편차를 떨어뜨리는 처리가 필요하게 됩니다. 그 처리에는 Flat Field 보정이 사용됩니다.
Pyhton과 OpenCV를 사용하여 배경 이미지 처리를 기억하기 위해 설명합니다.

Flat Field 보정



천체 사진 촬영(촬영 시 보정)



Flat Field 보정은 천체 촬영 시 사용됩니다.
참고 1
Starry Urban Sky
참고 2
플랫 보정 처리란?
참고 3
플랫 프레임 촬영 방법

참고하듯이
라이트 프레임(LF):일절 아무런 처리도 하지 않고, 찍은 그대로의 화상
다크 프레임(DF):라이트 프레임과 같은 촬영 조건으로 카메라에 캡을 해 밖으로부터의 빛이 들어가지 않도록 한 촬영 화상
플랫 프레임(FF): 라이트 프레임과 같은 촬영 조건에서 아무것도 찍히지 않고 빛의 분포만이 기록된 화상
이러한 이미지에서 보정 이미지를 다음과 같이 이미지 처리합니다.
보정 화상:(LF-DF)/(FF-DF)

덧붙여서 분광 측정에서의 반사율 측정에서도 같은 처리를 실시하고 있습니다.
반사율 = (측정 샘플의 반사 강도 - 다크 프레임)/(참조의 반사 강도 (예를 들어 Al 등) - 다크 프레임)

이미 획득한 이미지(촬영 후)에서의 처리



참고 4
배경 제거 정보
대부분의 경우 이미 이미지가 있고 이 이미지에서 입자의 수를 자동으로 카운트해 달라고 부탁되므로 위에서 설명한 것과 같은 처리는 할 수 없습니다.
이제 한 이미지에서 배경 처리를 수행해야합니다. 그래서 원본 이미지에서 플랫 프레임을 만듭니다.
플랫 프레임은 원본 이미지(라이트 프레임)에 Mean 필터링을 수행하여 원본 이미지의 평균 밝기를 적용합니다. (Mean 필터는 픽셀 범위를 약간 크게 하여 미세한 구조가 없어집니다.)

보정 화상:라이트 프레임(원 화상)/플랫 프레임(Mean 필터 후의 화상 × 평균 휘도)

시도한 환경



Windows 10 Pro
아나콘다
파이썬 = 3.7
conda = 4.9
numpy = 1.18.5
opencv = 4.2.0 (conda-forge에서 설치)

실제



참고 4에 게재되고 있는 화상 데이터를 이용해 Python으로 Flat Field를 실장해 보았습니다.
import cv2
import numpy as np
import matplotlib.pyplot as plt

# 処理前と処理後の比較のPlot
def bef_aft_img_show(img1,img2):
    print(f'average brightness:{img1.mean():.1f}, {img2.mean():.1f} ')
    plt.figure(figsize=(10,10))
    plt.subplot(121),plt.imshow(img1),plt.title('Original')
    plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.imshow(img2),plt.title('After')
    plt.xticks([]), plt.yticks([])
    plt.show()

# ImageとHistgramのPlot
def image_hist_show(img):
    print(f'Shape:{img.shape},type:{img.dtype}')
    print(f'Average Brightness:{img.mean():.1f}')
    hist = cv2.calcHist([img],[0],None,[256],[0,256])

    plt.figure(figsize=(10,5))
    plt.subplot(121),plt.imshow(img),plt.title('Image')
    plt.xticks([]), plt.yticks([])
    plt.subplot(122),plt.plot(hist),plt.title('Histgram')
    plt.show()


# 画像読み込み(OpenCVを利用しています)
file_path = './data/samp_Gradation1.bmp' # 適宜変更してください。
img = cv2.imread(file_path, cv2.IMREAD_GRAYSCALE)
image_hist_show(img)

Shape:(256, 256),type:uint8
Average Brightness:111.5


# Flat Frameの作成
# Meanフィルタリングを行う。
# 参考:画像の平滑化
# http://whitewell.sakura.ne.jp/OpenCV/py_tutorials/py_imgproc/py_filtering/py_filtering.html

dst = cv2.blur(img, (50, 50)) 
# 通常引数として(3,3)とか(5,5)を入力しますが、全体的な明暗を取り除くために大きい値にしている
# 適当に値を調整してください。

image_hist_show(dst)
Shape:(256, 256),type:uint8
Average Brightness:111.7


# 元画像 / Mean フィルタ後の画像 × 平均輝度
avg_hist = img.mean()
ffc = (img/dst)*avg_hist

print(ffc.dtype)
# >>> float64
# float64になっているので、この後OpenCVの関数を利用するためにunit8にしています。
cast_ffc = ffc.astype('uint8')
image_hist_show(cast_ffc)

# この画像を保存する場合
# cv2.imwrite('case1_ffc.png', ffc)
float64
Shape:(256, 256),type:uint8
Average Brightness:110.3


#処理前処理後の比較
bef_aft_img_show(img,cast_ffc)
average brightness:111.5, 110.3 


# 参考資料4にあった、
# 元画像 - Mean フィルタ後の画像 + 平均輝度 
# の処理である程度背景処理ができるならばそれでも良いと思います。

l_ffc = img - dst + avg_hist
cast_l_ffc = l_ffc.astype('uint8')
image_hist_show(cast_l_ffc)
Shape:(256, 256),type:uint8
Average Brightness:110.8



ImgeJ에 구현 된 rolling ball algorithm이라는 것이 있습니다.
이를 위해 아래 사이트에 Python 패키지가 있습니다.

pip에서만 설치할 수 있습니다.
또한 경우에 따라 opencv-python도 설치되므로이 패키지를 사용한다면 새롭게 가상 환경을 만들고 시도하는 것이 좋습니다. 실제로 사용해 보았지만 계산에 약간의 시간이 걸립니다.
from cv2_rolling_ball import subtract_background_rolling_ball

img_rg, background = subtract_background_rolling_ball(img, 30, light_background=True,
                                     use_paraboloid=False, do_presmooth=True)

image_hist_show(img_rg)   
Shape:(256, 256),type:uint8
Average Brightness:246.0



요약



이미 있는 화상으로부터 평균화 처리를 실시해 플랫 화상을 작성해, Flat Field 처리를 실시했습니다.

좋은 웹페이지 즐겨찾기