728x90

이전 블로그에서 카메라 렌즈 종류에 대해서 소개 했었는데, 그 렌즈 중에는 라인 스캔 카메라가 있었습니다. TDI (Time Delay Integration) 라인 스캔 카메라는 고속으로 이동한는 물체를 고해상도로 촬영하기 위해 설계된 특수한 라인 스캔 카메라로 볼 수 있습니다. 보통 한 라인을 이용하여 이미지를 만드는 경우 작은 영역에 한 번만 노출되기 때문에 감도가 낮고 노이즈에 취약할 수 있습니다.

 

TDI 라는 명칭에서 처럼 시간 지연을 통한 적분 기술을 이용하여 고감도 이미지를 만듭니다. TDI에서는 1 X N 라인을 이용하며, 이미지 센서에 여러 라인이 배열되어 있어 대상이 이동함에 따라 각 라인이 같은 위치를 순차적으로 촬영 및 누적합니다. 예를 들어 N = 64 라면 물체의 동일한 위치를 64번 촬영한다는 의미로 볼 수 있고, 신호는 64배 증가하고 노이즈는 8배 증가하므로 SNR(Signal to Noise Ratio)이 향상됩니다. 

 

TDI 라인 스캔 카메라의 특징은 라인 수를 증가 시킬 수록 고감도 이미지를 얻을 수 있으며 노이즈 감소와 빠르게 이동하는 물체에 대해 고속 촬용이 가능합니다. 따라서 컨베이어 벨트에 제품을 이동시키면서 검사하는 산업 분야인 PCB 검사, 인쇄물 검사 등에 많이 활용됩니다. 그림에서 같이 라인 수에 따라 Single Line, Dual Line, TDI 형태로 구분 할 수도 있습니다.

 

 

 

TDI 활용 분야 중에는 반도체 검사가 있습니다. 웨이퍼에 이물질이나 결함 검사시에 이미지를 활용하는 경우가 많으며 수십 나노미터 또는 수 나노미터 크기의 노이즈 탐색 시 주요하게 활용됩니다. 일반적으로 반도체 분야에 사용되는 TDI는 256 라인 스캔이 활용되며, 컨베이어 벨트 예와 반대로 웨이퍼가 고정된 상태에서 라인 스캔이 이동함으로써 이미지를 구현합니다.

 

TDI의 이미지 합성은 1) N개 라인에 촬영된 이미지 배열을 같은 위치의 정보가 일치하도록 정렬하고, 2) 각 위치의 픽셀값을 전체 더하거나 평균값을 구합니다. 3) 마지막으로 출력할 이미지 Depth에 맞게 스케일링 될 수 있도록 정규화 합니다. 아래는 현 과정을 시뮬레이션 해 볼 수 있는 파이썬 예제 코드 입니다.

 

import cv2
import numpy as np
import matplotlib.pyplot as plt

# 가상으로 대상 이미지 생성
height, width = 100, 200
moving_obj = np.zeros((height, width), dtype=np.uint8)

# 대상 밝은 줄이 이동하는 효과
for i in range(height):
    moving_obj[i, 50 + (i % 50)] = 255  # 대각선 방향 밝기

# 일반 라인 스캔 (한 라인)
line_scan_img = np.zeros((height, width), dtype=np.uint8)
for i in range(height):
    line = moving_obj[i:i+1, :]  # 한 줄
    line_scan_img[i:i+1, :] = line

# TDI 라인 스캔 (8 라인 누적)
TDI_stage = 8
tdi_img = np.zeros((height - TDI_stage, width), dtype=np.uint16)
for i in range(height - TDI_stage):
    acc_line = np.zeros_like(line, dtype=np.uint16)
    for j in range(TDI_stage):
        acc_line += moving_obj[i + j:i + j + 1, :]
    tdi_img[i:i+1, :] = acc_line

# 정규화(스케일링)
tdi_img_norm = cv2.convertScaleAbs(tdi_img, alpha=255.0 / (TDI_stage * 255))

# 결과 보기
plt.figure(figsize=(12, 6))
plt.subplot(1, 3, 1)
plt.title("Original Moving Image")
plt.imshow(moving_obj, cmap='gray')

plt.subplot(1, 3, 2)
plt.title("Line Scan Image")
plt.imshow(line_scan_img, cmap='gray')

plt.subplot(1, 3, 3)
plt.title("TDI Result (8 stages)")
plt.imshow(tdi_img_norm, cmap='gray')

plt.tight_layout()
plt.show()
728x90
728x90

이미지 분석을 위한 특성은 이미지 센서 및 렌즈 특성에 따라 달라질 수 있습니다. 칼라 이미지는 Red, Blue, Green이라는 파장을 렌즈에서 필터링 해서 만들어 질 수 있으며, 렌즈 수차에 따라 이미지 왜곡이 발 생할 수 도 있습니다. 특히 산업 분야에서 활용되는 광학 현미경 Microscope 에서 렌즈 특성은 용도에 따라 중요하며, 현 블로그에서는 주요 기본 용어에 의미와 특징을 알아보겠습니다.

 

색상과 파장 (Color and Wavelength)

광학 분야에서 빛을 설명할 때 파장으로 정의합니다. 빛을 받아드릴때 어떤 파장을 필터링하느냐에 따라서 렌즈의 특성이 달라질 수 있습니다. 파장은 크게 자외선(380nm 미만), 가시광선(380~750nm), 적외선(770nm 이상) 으로 구분되며, 770nm 이상에서 이미지를 취득하는 카메라를 적외선 카메라라고 합니다.

 

배율 (Magnification)

카메라에서 배율은 피사체의 실제 크기와 이미지 센서 상에 맺힌 상의 크기 비율을 의미합니다. 배율을 정의해 보면 “센서 상의 이미지 크기 / 실제 물체의 크기”이며, 예를 들어 물체의 실제 크기가 50mm이고 센서 상에 5mm로 맺혔다면 배율은 0.1가 됩니다.

 

광학 현미경 렌즈에 “20x”, “50x”, “100x”로 표시된 것을 볼 수 있으며 배율을 의미합니다. 20배, 50배, 100배로 확대할 수 있다는 의미이며 배율 계산시 정의는 아래와 같습니다. 중간 배율이 없으면 제외하고 계산합니다.

 

배율(M) = 대물렌즈(Objective) 배율 X 접안렌즈(Eyepiece) 배율 X 중간(Intermediate tube) 배율

 

개구수 (Numerical Aperture)

개구수 NA는 대물렌즈를 통과한 빛과 광축이 이루는 최대각과 매질의 굴절률을 이용하며, 분해능과 밝기, 초점심도 등을 결정하는 중요한 수치입니다. 개구수 값이 클수록 광학 현미경의 분별 가능한 최소 길이가 작아집니다. 개구수 NA를 구하는 공식은 아래 같습니다.

 

N.A = n X sinθ

 

n: 시료와 대물렌즈 사이 매질의 굴절률 ( 공기: 1.00, 물: 1.33)

θ: 렌즈의 중심축(광축)과 제일 외측을 지나는 광선 간 이루는 각도

 

 

추가로 분해능 Resolving Power을 구하는 공식은 아래와 같습니다.

 

분해능 R = λ / (2 X N.A)

 

수차 (Aberration)

이미지 센서에 상을 맺을 때 한점에서 나온 빛이 광학계를 지난 다음 한 점에서 모이지 않아 영상에 색깔이 있어 보이거나 일그러지는 현상을 말합니다. 수차에는 크게 구면 수차와 색 수차가 있습니다.

 

렌즈도 하나의 매질로 볼 수 있으며 빛이 통과하게 되면 파장이나 진폭등이 변하게 되고 명도 및 채도도 변하게 됩니다. 렌즈를 지나면서 생기는 수차를 구면 수차라고 하며, 파장 길이에 따라 발생하는 것이 색 수차 입니다.

 

밝기와 작동거리(WD, Working Distance)

센서 맺히는 상의 밝기는 광원의 밝기 외에도 개구수나 배율의 영향을 받습니다. 개구수가 높을 수록, 배율이 낮을 수록 상의 밝기는 밝아집니다. 작동거리는 렌즈 끝에서 피사체가 있는 곳까지의 거리를 말합니다. 렌즈가 작동할 수 있는 거리이며 이 거리는 렌즈와 피사체가 맞닿지 않는 범위를 의미합니다. 작동거리가 길다고 해서 무조건 좋다고 할 수 없는데 WD와 NA는 반비례하기 때문입니다.

728x90
728x90

기존 블로그 에서 산업 자동화에 활용되는 머신 비전용 렌즈인 Telecentric Lens, Macro Lens, Line Scan Lens를 소개했습니다. 아래 링크를 참고해 보시면 좋을 듯 합니다.

2025.06.29 - [영상처리 도구] - 머신 비전 Machine Vision을 위한 카메라 렌즈 종류와 선택(1)

 

아래는 이 외에 머신 비전에서 활용되는 렌즈들 입니다. 활용 분야에 따라 렌즈의 적절한 선택은 효율성이나 비용 측면에서 더 유리할 수 있습니다.

 

고정 초점형 렌즈 (Fixed Focal Lens)

초점 거리가 고정되어 있어 화각이 일정하고 줌이 불가능한 렌즈를 의미합니다. 하지만 광학 성능이 우수하고 구조가 단순하여 PCB 패턴, 바코드, 약품 포장 라벨 검사 등등 산업용 검사나 머신 비전 분야에 널리 사용됩니다. 

 

명칭 그대로 고정 초점이기 때문에 해상도와 왜곡 보정에 유리하고 구조가 간단하여 유지보수가 용이합니다. 가격 측면에서도 효율성이 있어 산업용으로 많이 활용됩니다. 당연히 초점 거리 변경이 필요하면 렌즈 자체를 교체해야 하며 촬영 물체들의 높낮이가 변동이 있으면 사용이 불가 합니다.

 

무왜곡 렌즈 (Zero-Distortion Lens 또는 Ultra Low Distortion Lens)

광학 이미지에서 발생할 수 있는 기하학적 왜곡 Geometric Distortion을 최대한 제거하나 최소화한 렌즈를 말합니다. 다시 말해 왜곡률을 극한까지 줄여 실제 대상의 형태를 왜곡 없이 촬영하는 렌즈이며, 산업 검사와 비전 시스템 등 정확한 기하학적 재현이 요구되는 분야에 필수로 사용됩니다.

 

왜곡률의 경우 일반 렌즈 1~3%, 광각 렌즈 3~10% 이상, 무왜곡 렌즈 0.1% 이하로 볼 수 있으며, 광학 측정 장비나 생물학 영상, 문자 스캔, 실물 재현을 위한 건축물 및 문화재 촬영에 사용될 수 있습니다. 렌즈 설계 복잡성으로 가격이 비싸며 화각 FOV가 제한적일 수 있습니다. 

 

Pericentric 렌즈

360도 시야 확보용 렌즈로 렌즈 하나로 물체의 상단과 측면, 일부 바닥까지 한번에 볼 수 있도록 설계된 렌즈 입니다. 특히 원형 물체나 튜브용 물체의 외곽을 한번에 검사해야 할 때 활용됩니다.

 

일반 렌즈와 다르게 광선이 센서 중심을 향해 굴절 되도록 설계되어 센서가 보는 시야는 렌즈를 중심으로 물체를 감싸는 형태가 됩니다. 결과론적으로 물체의 위와 측면을 동시에 이미지화 할 수 있으며, 병뚜껑 밀봉 상태나 병과 캔의 레이블 위치, 화장품 튜브 외곽 인쇄 품질 검사 등에 사용됩니다.

 

그림에서와 같이 플라스틱 통의 뚜껑을 기준으로 촬영을 하면 플라스틱 측면에 라벨까지 이미지로 확인 할 수 있습니다. 그림에 WD는 Working Distance를 의미합니다.

 

 

전동식 렌즈 (Motorized Lens)

명칭에서와 같이 전동식으로 초점, 줌, 조리개 등을 자동으로 조절할 수 있는 렌즈 입니다. 시스템 명령이나 소프트웨어를 통해 원격으로 제어할 수도 있습니다. 따라서 넓은 지역을 감시하면서 특정 지점을 확대해 볼 수 있는 감시 시스템이나 다양한 거리의 물체 인식을 필요로 하는 로봇 비전에서 활용될 수 있습니다. 요즘 골목마다 설치 되어 있는 CCTV가 전동식 렌즈의 한 예 입니다.

 

원격 제어 가능함과 자동화 시스템의 연동으로 정밀한 제어에 장점을 가지며 전원 의존성이나 비용, 설정 복잡성 등은 단점으로 생각할 수 있습니다.

728x90
728x90

이미지 처리 및 분석을 통한 기술 적용 분야가 많아지고 있습니다. 그 중 컴퓨터 비전 Computer Vision의 한 부분인 머신 비전 분야가 있습니다. 머신 비전은 산업 자동화와 제조 라인의 검사, 품질 관리, 제어 등에 사용되며, 그 이미지를 취득하는 다양한 비전 카메라들이 있습니다. 현 블로그에서는 비전 카메라에 장착되는 렌즈에 특성을 알아보겠습니다. 

 

텔레센트릭 렌즈 (Telecentric Lens)

광학 중심이 물체나 제품쪽으로 이동하면서도 배율이 일정하게 유지되도록 설계된 특수 렌즈이며, 정밀한 측정 및 검사에 사용됩니다. 특성을 보면 배율이 일정하고 일반 렌즈에 비해 왜곡을 최소화합니다. 일반 렌즈는 조리개가 렌즈 중간에 위치한 반면 텔레세트릭 렌즈는 조리개가 주점(Primary principal point) 위에 배치되어 광선이 평행하게 입사 및 출사할 수 있는 구조적 특징을 가지고 있습니다.

 

이러한 구조적 특성에 의해 물체의 왜곡을 최소화하고 깊이 변화에 무관한 정확한 크기 측정이 가능하며 동일한 조건에서 반복 측정이 가능한 장점을 가지고 있습니다. 반면 고가에 렌즈가 길고 무거우며 조리개가 작아 광량 손실이 있는 단점과 검사 대상 물체 크기가 렌즈 직경보다 작아야 한다는 단점을 가집니다. 세부적으로 반도체 검사나 PCB 및 전자부품 측정, 3D 스캐닝 시스템 등에 활용됩니다.

 

종류로는 아래 세가지로 구분할 수 있습니다. 아래 그림은 Bi-Telecentric Lens 구성도와 일반 렌즈 및 텔레센트릭 간 촬영한 물체를 비교한 예입니다. 일반 렌즈에서는 원근에 따른 물체의 크기가 다르지만 텔레센트릭 렌즈에서는 같은 크기의 물체는 동일하게 촬영됩니다.

 

1) Object-space Telecentric Lens: 물체가 렌즈에 가깝거나 멀어도 배율이 일정

2) Image-space Telecentric Lens: 이미지 센서에 광선이 평행하게 입사, 이미지 센서 크기에 무관하게 균일한 이미지 품질 유지

3) Bi-Telecentric Lens: 물체 및 이미지 센서 모두 Telecentric. 

 

 

 

매크로 렌즈 (Macro Lens)

작은 사물 또는 제품 등을 크게 확대하여 촬영할 수 있도록 설계된 특수 렌즈이며, 주로 접사(Close-up photography)에 사용됩니다. 일반적으로 곤충이나 꽃, 작은 전자부품 및 인쇄패턴과 같은 미세한 부분 촬영에 적합합니다.

매크로 렌즈의 특성은 배율이 크며 촬영 대상의 왜곡을 최소화하고 얕은 심도(Depth of Field)를 가집니다. 초점 거리별 유형을 보통 50~60mm는 문서 등의 근거리 접사, 90~105mm는 곤충이나 꽃 접사 촬용에 사용되며 150~200mm는 원거리 접사로 산업용 검사에 활용됩니다.

 

라인 스캔 렌즈 (Line Scan Lens)

라인 스캔 카메라와 함께 사용하는 특수 렌즈로 한 줄(Line)의 이미지를 정밀하게 촬용하기 위해 설계된 렌즈입니다. 우리가 일반적으로 사용하는 영역 스캔 (Area Scan) 방식과는 다른 연속적으로 고속 이미지 취득에 최적화 되어 있습니다.

 

라인 스캔은 한번에 물체의 가로 또는 세로의 한 줄만 촬영이 되며, 대상이 이동하면서 연속 라인 촬영을 통해 2차원 이미지를 구성합니다. 문서를 스캔할 때 방식과 유사하다고 보면 됩니다. 라인 스캔 렌즈의 특징을 보면 미세 결함도 감지할 만큼 해상도가 높고 전체 라인에 걸쳐 왜곡 없이 균일합니다. 그리고 균일하게 밝기를 유할 수 있는 광량 균일성과 열이나 진동에 강건하게 장시간 연속 촬영이 가능합니다.

 

아래 그림에서와 같이 라인 스캔 렌즈로 촬영된 이미지는 일반적으로 X축이 시간으로 볼수 있이며, Y축이 라인 스캔의 라인 크기입니다.

 

728x90
728x90

이미지를 다루다 보면 다양한 포맷들을 볼 수 있습니다. 실생활에서도 비트맵 Bitmap 이미지를 많이 사용하기도 하며 MFC와 C# 윈폼에서 화면에 그려주는 이미지가 비트맵이기도 합니다.

MFC (Microsoft Foundation Class) 라이브러리를 이용하여 비트맵을 만들어 화면에 출력하거나 파일로 저장하는 과정을 살펴 보겠습니다. 단계별로 보면, 메모리 DC 생성을 하고 비트맵 객체 생성, 그리기 작업을 수행합니다. 이후 비트맵 이미지를 저장하거나 화면에 출력하고 리소스 해제를 하면 끝입니다.

 

GDI (Graphics Device Interface) 그리기

memDC.FillSolidRect(0, 0, width, height, RGB(255, 255, 255)); // 배경 흰색

memDC.TextOutW(10, 10, _T("Hello Bitmap!!!")); // 텍스트 출력 

화면에 출력 또는 저장

pDC->BitBlt(0, 0, width, height, &memDC, 0, 0, SRCCOPY);  // 화면 출력

 

CImage image; // 저장

image.Attach((HBITMAP)bitmap.Detach()); // CBitmap → HBITMAP → CImage

image.Save(_T("output.bmp")); 

리소스 해제

memDC.SelectObject(pOldBitmap); // 원래 비트맵으로 복원

bitmap.DeleteObject(); // 리소스 해제

memDC.DeleteDC(); // 리소스 해제

 

OnDraw 함수를 이용한 전체 코드는 아래와 같습니다. 이미지를 화면에 출력시 Device Context(pDC)의 BitBlt 함수를 이용하는 것을 볼 수 있습니다. 함수 별 활용법을 알아두면 실무 개발에 많은 도움이 될 수 있습니다.

 

void CMyView::OnDraw(CDC* pDC)
{
    int width = 100;
    int height = 100;

    CDC memDC;
    memDC.CreateCompatibleDC(pDC);

    CBitmap bitmap;
    bitmap.CreateCompatibleBitmap(pDC, width, height);
    CBitmap* pOldBitmap = memDC.SelectObject(&bitmap);

    // 배경 및 텍스트 출력
    memDC.FillSolidRect(0, 0, width, height, RGB(200, 220, 255));
    memDC.TextOutW(10, 10, _T("Hello Bitmap!!!"));

    // 화면에 출력
    pDC->BitBlt(0, 0, width, height, &memDC, 0, 0, SRCCOPY);

   
    // 리소스 정리
    memDC.SelectObject(pOldBitmap);
    memDC.DeleteDC();
}

 

 

추가로 비트맵 헤더 정보는 아래와 같고 실제 프로그래밍 시 각 요소에 접근이 필요할 때가 있습니다. 압축 설정에는 여러 종류가 있으며 일반적으로 무압축 BI_RGB를 설정 합니다.

 

typedef struct tagBITMAPINFOHEADER {
  DWORD biSize;
  LONG  biWidth;
  LONG  biHeight;
  WORD  biPlanes;
  WORD  biBitCount;
  DWORD biCompression;
  DWORD biSizeImage;
  LONG  biXPelsPerMeter;
  LONG  biYPelsPerMeter;
  DWORD biClrUsed;
  DWORD biClrImportant;
} BITMAPINFOHEADER, *LPBITMAPINFOHEADER, *PBITMAPINFOHEADER;

 

 

728x90

+ Recent posts