Reference
Contributor
1. Calibration의 의미
이미지 파일의 구조에 대한 글에서, 이미지는 2차원 공간상에 위치한
pixel
의 집합이라고 말씀드렸습니다.대개
pixel
하나당 흑백(Grayscale
) 이미지의 경우 숫자 하나가, 컬러 이미지의 경우 숫자 3개가 RGBchannel
의 형태로 할당되어 있습니다.그러나 이미지에 찍힌 대상의 실제 크기는
pixel
과 다른,meter
등의 단위로 이루어져 있습니다. 이를 보정하는 과정을calibration
이라고 하며,scale
을pixel
단위 길이나 넓이에 곱합니다.ImageJ
에서 이미지를 열고 포인터를 그림 위에 올리면, 메인 창에x
,y
좌표와 함께pixel
값이 나옵니다.
- 그러나 어떤 이미지는
ImageJ
메인 창의x
,y
좌표,pixel
값에 괄호()
가 붙어있습니다. - 아래 예제의 원본은 여기에서 다운로드 받을 수 있습니다.
- 괄호 안의 값은
pixel
단위, 괄호 밖의 값은 보정된(calibrated
) 실제 길이입니다. - 이미지 우측 하단 $ 2\ \mu\text{m} $ scale bar의 길이는 484 px 입니다.
- 메타데이터로부터 얻은
scale
이 4.13 nm/px이므로, 확인을 위해 곱해보면 $ 484 \times 4.13 = 1998.92\ \text{nm} $ 이므로 $ \approx 2 \mu\text{m} $ 입니다.
ImageJ
Calibration
은 크게 두 가지로 나뉘어집니다.- Spatial Calibration :
x
,y
등 길이 방향을 보정합니다. - Density Calibration:
pixel
값을 보정합니다.
- Spatial Calibration :
2. Calibration의 활용
Calibration이 된 이미지를 이용해 측정해봅시다.
DEM
: Digital Elevation Model이라는 종류의 데이터가 있습니다.- 이미지 형식이지만
pixel
에 담긴 값은 해당 위치의 고도를 의미합니다. - 제한된 값(8 bit Grayscale 이미지: 0~255) 값만으로 훨씬 넓은 범위의 고도를 파악해야 하므로
pixel
값에 scale이 적용되어 있습니다.
여기에서 이미지를 다운로드받아
ImageJ
에서 엽니다.Image > Lookup Tables
에서Green Blue Fire
를 선택합니다.흔히
LUT
라고 말하는 Loopup Table은 Grayscale에 담긴 Scalar 값을 시각화할 colormap입니다.실제 값은 변경하지 않고
ImageJ
에서 보여주는 시각적인 효과만 변경됩니다.Analyze > Surface Plot
을 선택하고 옵션에서Draw Wireframe
,Shade
,Draw Axis
,Smooth
를 선택합니다. 2차원 그림이 3차원으로 변환됩니다. z 축 숫자를 보면 167 ~ 2408로 표시되어 있습니다.Calibration
이 적용된 것입니다.Analyze > 3D Surface Plot
을 선택해도 비슷한 그림을 얻을 수 있습니다. 3D 회전을 비롯해서Grid Size
,Smoothing
등을 실시간으로 조정할 수 있는 interactive plot입니다. 여기서는 z 축에Calibration
이 적용되지 않았습니다.
3.Calibration (GUI)
3.1. Spatial Calibration (GUI)
이미지의 Scale Bar를 이용하여 Spatial Calibration을 설정해 보겠습니다.
메인 창에서 Line Selection Tool을 선택하고 Scale Bar를 따라 선을 긋습니다. 첫 지점을 클릭하고
shift
키를 누른 채 마우스를 이동하면 포인터를 수평으로만 움직일 수 있습니다.Calibration을 적용할 이미지를 여기에서 다운로드받아
ImageJ
에서 열고,Analyze > Set Scale...
을 선택하여 Scale 설정 창을 엽니다.조금 전 손으로 그었던 선의 길이가
Distance in pixels
로 483이 나옵니다.Scale Bar에 $2\ \mu \text{m} = 2000\ \text{nm}$ 라고 되어 있으므로
Known distance
에 2000을 입력하고Unit of length
에 nm를 입력합니다.본 이미지에만 적용할 Calibration이므로
Global
은 체크되지 않은 채로 놔둔 채OK
를 누르면 Calibration이 적용됩니다.
방금 설정한 Calibration을 이용하여 Particle의 지름을 측정해 보겠습니다.
지름을 잴 Particle을 정하고, Line Selection Tool을 이용해서 지름에 맞춰 선을 긋습니다.
Analyze > Set Measurements
에서 측정할 항목을 선택합니다.Angle
과Length
는 기본으로 출력되니 추가로 얻을 값들을 선택하고, 필요 없는 값들을 선택 해제하면 됩니다.Analyze > Measure
를 선택하면 Results 창이 뜨고Length = 896.401
이 출력됩니다. Results 창에서File > Save as...
를 선택하면.csv
파일로 저장할 수 있습니다.Analyze > Plot Profile
을 선택하면 Particle의 지름을 가로지르는 선을 따라 Intensity Profile을 얻을 수 있습니다.
ImageJ
에서 이미지에 Scale Bar를 삽입할 수 있습니다.Analyze > Tools > Scale Bar...
를 선택합니다.Scale Bar
창에서 Calibration 단위(nm
) 기준의 길이와 Scale Bar의Height
,Font Size
,Location
등을 설정합니다. 설정값에 따라 이미지 위에 실시간으로 Scale Bar가 생성되니 보시면서 원하는 상태로 설정하면 됩니다.$2000\ \text{nm}$ 대신 $2\ \mu \text{m}$로 출력되기를 원하시면, calibration을 $\mu \text{m}$ 단위로 진행하시면 됩니다.
3.2. Density Calibration (GUI)
Density Calibration을 위해선 다음 두 가지 사항이 필요합니다.
- 두 지점 이상의
pixel
과 데이터(value
) 쌍 - Density Calibration의 함수(
function
): Linear? Polynomial? Exponential?
- 두 지점 이상의
Density Calibration을 위한 데이터가 주어지면 좋지만, 그렇지 않은 경우 이미지 한켠의 범례(
legend
)를 이용해서라도 입력해야 합니다.GeoTIFF
이미지 데이터를 이용해서 Density Calibration을 해 보겠습니다.GeoTIFF
형식은 지리정보(GIS)와 기상 분야에 주로 사용되며, 이미지 외에도map projection
,coordinate systems
,ellipsoids
등의 데이터를 함께 담고 있습니다.- 여기에서 예제파일을 다운받습니다.
ImageJ
에서 파일을 열고,Analyze > Calibrate
를 선택합니다.Calibrate
창에서, 왼쪽에pixel
값을 넣고 오른쪽은 이에 해당하는value
를 넣어줍니다.- 왼쪽 공간에 0과 254를 넣습니다. 데이터 사이는
Enter
키로 띄워줍니다. - 오른쪽 공간에 -2와 45를 넣습니다. 역시
Enter
키로 분리해 줍니다. - 섭씨 온도 데이터입니다.
unit
에 해당하는 곳에Degrees Celsius
를 넣습니다. - 1차식 데이터이므로 Function 메뉴에서
Straight Line
을 선택합니다. OK
를 누르면Calibration Function
이 보일 것입니다.Calibration Function
을 닫고 이미지 위에 마우스를 가져가면, 메인 창에 포인터가 위치한 지점의 x, y 좌표와 함께 value가 보입니다.- 이미지를
File > Save As
에서.tif
형식으로 저장하면Calibration
이 함께 저장됩니다.
- 왼쪽 공간에 0과 254를 넣습니다. 데이터 사이는
Density Calibration을 이용해 이미지 데이터 분석을 해 보겠습니다.
Analysis > Set Measurements
에서Area
,Mean gray value
,Standard deviation
,Modal gray value
,Min & Max gray value
를 선택하고OK
를 눌러 창을 닫습니다.Analysis > Measurement
를 클릭하면 Results창이 뜹니다.- Set Measures에서 지정한 분석 결과가 담겨 있습니다.
Scale Bar처럼 Density Calibration을 Legend로 삽입할 수 있습니다.
Analyze > Tools > Calibration Bar...
를 선택합니다.Scale Bar와 대체로 비슷하지만
Number of Labels
,Decimal Places
,Zoom Factor
등 다른 인자들이 있습니다.직접 인자를 바꿔가면서 Legend가 실시간으로 어떻게 변하는지 살펴보시기 바랍니다.
4.Calibration (python script)
4.1. Spatial Calibration (python script)
python
script를 이용해 현재의Calibration
값을 확인하고, 새로운Calibration
을 적용하겠습니다.getCalibration()
으로 현재 이미지의Calibration
값을 읽고,calibration().pixelWidth
와calibration().pixelHeight
를 수정해Calibration
을 수정합니다.마지막으로
setCalibration()
으로 새 이미지에 바뀐 값을 저장합니다.- 같은 이미지를
ImageJ
에 띄워 놓고, script 창을 열고 아래 코드를 붙여넣고 실행합니다.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24from ij import IJ, ImagePlus
from ij.plugin import Duplicator
# 1. Get Open Image
imp = IJ.getImage()
# 2. Get Initial Calibration
cal = imp.getCalibration()
print 'before Calibration:', cal
# 3. Duplicate Image
imp2 = Duplicator().run(imp)
# 4. Apply New Calibration
scale = 4.13 # nm/px
cal.pixelWidth = scale # pixelWidth : Pixel width in 'unit's
cal.pixelHeight = scale # pixelHeight : Pixel height in 'unit's
cal.unit = 'nm'
print 'after Calibration:', cal
imp2.setCalibration(cal)
# 5. Show New Image
imp2.title = 'Calibrated'
imp2.show()- 실행 결과
- 새 창으로 뜨는
Calibration
이 적용된 이미지는 처음 이미지와 동일해 보입니다. - 그러나 Scale Bar를 따라 Line Selection Tool을 긋고
Analyze > Measure
를 실행하면Length = 2007.180
이라는 값이 나옵니다. Calibration
을 적용하기 전 값은Length = 8.643
으로, 성공적으로 적용되었음을 알 수 있습니다.- 이상적으로는
Length = 2000
이 나와야 하지만, Line Selection을 할 때 손끝에서 발생한 오차로 인해 다소 크게 측정된 것입니다.
- 같은 이미지를
4.2. Density Calibration (python script)
Density Calibration 또한
python
script를 이용해 진행할 수 있습니다.먼저, 위 2.4.1 코드와 실행 결과를 보면 현재의
Calibration
을 읽어서cal
이라는 변수에 저장하고 출력한 결과가w
,h
,d
,unit
,f
,nc
,table
,vunit
,bd
로 출력됩니다. 각각의 의미는 다음과 같습니다.
변수 이름 Variable Name |
전체 이름 Full Name |
의미 Meaning |
기본값 Default Value |
---|---|---|---|
w | pixelWidth | pixel width scale (unit/px) | 1.0 |
h | pixelHeight | pixel height scale (unit/px) | 1.0 |
d | pixelDepth | pixel depth scale (unit/px) “slice 한 장의 두께” |
1.0 |
unit | unit | spatial unit of real world | “inch” |
f | function | density calibration fitting function | 20 |
nc | coefficients.length | function의 coefficient 수 (ex. y = a + bx : nc = 2) |
null |
cTable | cTable.length | bitDepth에 대응되는 real value 수 (ex. bd = 8 : Table size = 256 by 2) |
null |
vunit | valueUnit | density unit of real world | Gray Value |
bd | bitDepth | data depth. 2^bd. (ex. 256 = 2^8 : bd = 8) |
8 |
공식문서에서 이 부분에 대한 설명이 매우 불친절합니다.
자세한 설명은 소스코드를 열어 이해할 수 밖에 없었습니다. 상세한 설명이 있다면 제보바랍니다.
[ 관련 공식문서 링크 ] Calibration, CurveFitter, Constant Field Values
위에서 4개의 인자(
w
,h
,d
,unit
)는 Spatial Calibration에 연관된 것이고,
아래 5개의 인자(f
,nc
,cTable
,vunit
,bd
)는 Density Calibration에 연관된 것입니다.bd
=8이라면 0~255까지 256개의 값에 대응되는 value를 cTable로 입력해야 하기 때문에 Density Calibration을 python script로 수행하기엔 좀 성가십니다.따라서, Density Calibration을 python script로 수행할 때는 ImageJ > Tutorial > 5. Python Script 작성에 있는
IJ.run()
을 사용하시는 것을 추천합니다.- 2.3.2의 Density Calibration 과정을
IJ.run()
으로 옮기면 다음과 같이 한 줄로 표현됩니다.
1
IJ.run(imp, "Calibrate...", "function=[Straight Line] unit=[Degrees Celsius] text1=[0 254] text2=[-2 45] show")
- 메뉴의 Analyze > Calibrate…를 실행하되,
function
,unit
, pixel value(text1
), real value(text2
)를 넣고 calibration 결과를 보이라(show
)는 의미입니다. - 아래 코드를 실행하면 Density Calibration 전후의 parameter를 비교해서 보여줍니다.
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
31
32
33
34
35
36
37
38
39
40
41
42
43
44from ij import IJ, ImagePlus
from ij.plugin import Duplicator
# 1. Get Open Image
imp = IJ.getImage()
# 2. Get Initial Calibration
cal = imp.getCalibration()
f = cal.getFunction()
coef = cal.getCoefficients()
cTable = cal.getCTable()
vunit = cal.getValueUnit()
bd = imp.getBitDepth()
print 'before Calibration:', cal
print 'f:', f
print 'coef:', coef
print 'cTable:', cTable
print 'vunit:', vunit
print 'bd:', bd
# 3. Duplicate Image
imp2 = Duplicator().run(imp)
# 4. Apply New Calibration
IJ.run(imp, "Calibrate...", "function=[Straight Line] unit=[Degrees Celsius] text1=[0 254] text2=[-2 45] show")
imp2.setCalibration(cal)
# 5. Get Final Calibration
cal2 = imp2.getCalibration()
f = cal2.getFunction()
coef = cal2.getCoefficients()
cTable = cal2.getCTable()
vunit = cal2.getValueUnit()
bd = imp2.getBitDepth()
print 'after Calibration:', cal2
print 'f:', f
print 'coef:', coef
print 'cTable:', cTable
print 'vunit:', vunit
print 'bd:', bd
# 5. Show New Image
imp2.title = 'Calibrated'
imp2.show()Density Calibration
function
값이 20에서 0으로 변했습니다.
관련 공식 문서를 보시면 NONE에서 STRAIGHT_LINE으로 변경되었다는 의미라는 것을 알 수 있습니다.function
의 coefficient를 의미하는coef
는 None에서 array(‘d’, [-2.0, 0.18504…])가 되었습니다.
2.3.2의 y = a + bx 그래프에 도시된 계수가 바로 a = -2.0, b = 0.18504 입니다.cTable
은 None에서 어마무시한 숫자의 나열이 되었습니다.
위에서 말씀드린 ‘ 0~255까지 256개의 값에 대응되는 value’ 입니다.
- 2.3.2의 Density Calibration 과정을