스캔 성능 최적화 — Active Symbol Counts·Restrict Symbology·이미지 프로세싱 완전 가이드
최근 업데이트: 2026-05-01
한줄 요약
스캔 속도, 인식 거리, 이미지 프로세싱 효율을 결정하는 핵심 변수와 한국 도메인 환경 튜닝 패턴을 정리합니다. 사후 필터링 깊이는 별도 가이드로 연결됩니다.
TL;DR
- 스캔 성능 최적화는 4개 축으로 접근합니다: 속도(디코드 레이턴시), 거리(초점·해상도), 이미지 프로세싱 효율(CPU·배터리), 견고성(저조도·움직임·손상).
- 활성화 심볼로지 수를 줄이는 것이 단일 변수 중 ROI가 가장 큽니다 — 7개 → 1개로 줄이면 처리 시간 30~60% 절감.
- Active Symbol Counts로 가변 길이 심볼로지의 허용 자릿수를 좁히면 오인식과 CPU 부담이 동시에 감소합니다.
- Composite Code는 의약품·의료기기 등 명확히 필요한 경우에만 활성화하고, 일반 물류·리테일에서는 비활성화 유지.
스캔 성능을 결정하는 4가지 축
스캔 성능을 "인식이 되거나 안 되거나" 이분법으로 보면 최적화 포인트를 놓칩니다. 실무에서 성능은 네 개의 독립적인 축으로 분해됩니다. 각 축은 서로 다른 SDK 설정과 연결되고, 트레이드오프 방향도 다릅니다.
속도 — 디코드 레이턴시
디코드 레이턴시는 카메라 프레임이 SDK에 들어간 시점부터 인식 결과가 콜백으로 반환되는 시점까지의 시간입니다. 이 시간은 활성화된 심볼로지 수, 각 심볼로지의 가변 길이 허용 범위, Composite Code 활성화 여부에 직접 비례합니다.
한 국내 대형 택배사 분류 라인에서 측정한 데이터에 따르면, 7개 심볼로지를 동시 활성화한 초기 설정에서 Code 128 단일 심볼로지로 제한했을 때 디코드 레이턴시가 평균 52% 감소했습니다. 이 차이는 분류 컨베이어가 초당 처리하는 박스 수를 280개에서 480개 이상으로 끌어올리는 데 기여한 핵심 변수였습니다. 바코드 스캔 자체의 처리 속도가 병목이 되는 고속 라인 환경에서 심볼로지 최소화는 선택이 아니라 설계 원칙입니다.
거리 — 초점과 해상도
인식 가능한 거리는 카메라의 광학 특성(초점 거리, 최소 인식 가능 모듈 크기)과 SDK 설정(해상도, 디지털 줌) 두 요소에 의해 결정됩니다. 스마트폰에는 광학 줌이 없으므로 먼 거리의 작은 바코드를 읽으려면 해상도를 높이는 것이 가장 현실적인 방법입니다.
해상도를 720p(HD)에서 1080p(Full HD)로 올리면 동일한 물리적 거리에서 더 많은 픽셀로 바코드 세부를 포착할 수 있습니다. 단 해상도가 높을수록 디코더가 처리해야 할 데이터 양이 늘어 CPU 부하와 배터리 소모가 비례해서 증가합니다. 국내 창고의 고정 스캐너 환경처럼 전원 제약이 없는 경우에는 높은 해상도를 유지해도 무방하지만, 핸드헬드 단말기 기반의 피킹 앱에서는 거리와 배터리 수명 사이의 균형점을 현장 테스트로 확정해야 합니다.
광학 줌이 없는 스마트폰 환경에서 거리 변화가 큰 경우, CameraSettings.zoomFactor를 주요 작업 거리에 맞게 고정하고 나머지는 플랫폼 자동 초점(AF)에 맡기는 것이 현실적인 방법입니다.
이미지 프로세싱 효율 — CPU·GPU·배터리
이미지 프로세싱 효율은 단위 시간당 처리 가능한 프레임 수와 배터리 방전 속도로 나타납니다. 같은 인식률을 달성하더라도 처리 경로에 따라 배터리 소모가 2배 이상 차이날 수 있습니다.
videoResolution 설정은 이미지 프로세싱의 핵심 레버입니다. 해상도가 올라가면 디코더가 처리하는 픽셀 수가 제곱에 가깝게 증가합니다. 720p(1,280×720)와 1080p(1,920×1,080) 사이의 픽셀 수 차이는 2.25배이며, 4K(UHD, 3,840×2,160)는 1080p 대비 약 4배, 720p 대비 약 9배의 픽셀을 처리합니다. 최근 스마트폰들도 4K(UHD) 비디오 캡처를 지원하지만, 디코더가 처리할 픽셀이 1080p 대비 4배로 늘어 CPU·GPU·배터리 부하가 매우 높아 일반적으로 핸드헬드 환경에서는 권장하지 않습니다. 외부 전원이 공급되는 컨베이어 고정 카메라나 정밀 인식이 필요한 의약품 라인에서 적합합니다. 인식 대상 바코드가 크고 스캐너와의 거리가 가까운 환경이라면 해상도를 낮게 유지하는 것이 배터리 효율에 유리합니다.
프레임 레이트(초당 프레임 수)도 마찬가지입니다. SDK는 기본적으로 카메라 최대 fps로 동작하지만, 느린 컨베이어나 핸드헬드 스캐닝처럼 바코드가 빠르게 움직이지 않는 환경에서는 30fps로 제한해도 인식률에 영향이 없습니다. 처리 프레임 수를 절반으로 줄이면 CPU 사용량이 거의 선형으로 감소합니다.
견고성 — 저조도·움직임·손상
견고성은 "어려운 조건"에서도 인식이 성공하는 비율입니다. 국내 현장에서 자주 등장하는 어려운 조건은 세 가지입니다.
첫째, 저조도 환경. 국내 창고의 형광등(FL), 특히 노후 등기구는 50Hz 주기로 밝기가 변동합니다. 이 플리커가 카메라 노출 사이클과 어긋나면 특정 프레임에서 이미지가 어둡게 찍혀 인식률이 급락합니다.
둘째, 고속 이동. 택배 분류 컨베이어에서 바코드가 부착된 박스가 빠르게 이동하면 카메라 센서에 모션 블러가 생깁니다. 셔터 스피드(노출 시간)를 짧게 유지해야 블러를 억제할 수 있지만, 이는 이미지가 어두워지는 효과와 맞교환됩니다.
셋째, 바코드 손상·오염. 물류 현장에서 바코드가 긁히거나 습기·기름으로 오염된 경우입니다. Reed-Solomon 오류 복원이 있는 2D 바코드는 일정 손상까지 복원되지만, Code 128 같은 1D 바코드는 줄 하나가 지워져도 인식에 실패합니다.
이 네 축은 독립적이지 않습니다. 거리를 늘리기 위해 해상도를 높이면 이미지 프로세싱 효율이 떨어지고, 저조도 견고성을 위해 노출을 높이면 고속 이동 견고성이 약해집니다. 최적화는 이 트레이드오프를 현장 조건에 맞게 조율하는 과정입니다.
Restrict Symbology — 가장 큰 ROI의 첫 단계
SCANDIT SDK는 기본적으로 모든 심볼로지가 비활성화 상태입니다. 반대로 말하면, 프로젝트 초기에 "어떤 바코드를 읽어야 하는가"를 명확히 하지 않으면 여러 심볼로지를 습관적으로 활성화해 두는 실수가 발생합니다.
디코더는 매 프레임마다 활성화된 심볼로지 각각에 대해 독립적인 가설 평가를 수행합니다. 5개 심볼로지가 활성화되어 있으면 5개의 평가 경로를 병렬로 돌린다는 의미입니다. 이를 1개로 줄이면 동일한 하드웨어에서 처리 시간을 30~60% 절감할 수 있습니다.
"Scandit의 바코드 스캐너는 1D·2D 모든 종류의 바코드를 읽어낼 수 있습니다 […] 하지만 필요한 심볼로지만 활성화하면 처리 시간이 줄어듭니다." (Scandit Barcode Scanning Performance)
이 원칙을 한국 물류 현장에 적용하면 구체적인 설계 패턴이 됩니다. 국내 택배 분류 라인에서 처리하는 바코드는 대부분 Code 128 기반 운송장 번호입니다. EAN-13, QR코드, DataMatrix 등을 같은 세션에서 활성화해 둘 이유가 없습니다. 한 국내 물류 사업자가 7개 심볼로지 → Code 128 단일 구성으로 전환한 뒤 처리량이 280 scans/min에서 480 scans/min으로 개선된 사례는 이 원칙의 실효성을 잘 보여줍니다.
설정 방법은 플랫폼마다 다르지만 패턴은 동일합니다. 활성화할 심볼로지만 명시적으로 enabled: true로 설정하고, 나머지는 기본값(비활성화) 그대로 둡니다. 이미 활성화된 심볼로지가 있다면 enabled: false로 명시적으로 비활성화합니다.
iOS Swift — EAN-13 단일 활성화
import ScanditBarcodeCapture
let settings = BarcodeCaptureSettings()
settings.set(symbology: .ean13UPCA, enabled: true)
// 나머지 심볼로지는 기본 비활성화 상태 유지
Android Kotlin — EAN-13 단일 활성화
val settings = BarcodeCaptureSettings()
settings.enableSymbology(Symbology.EAN13_UPCA, true)
Web TypeScript — EAN-13 단일 활성화
const settings = await SDCBarcode.BarcodeCaptureSettings.fromJSON({});
settings.enableSymbology(SDCBarcode.Symbology.EAN13UPCA, true);
React Native — EAN-13 단일 활성화
const settings = new BarcodeCaptureSettings();
settings.enableSymbology(Symbology.EAN13UPCA, true);
Scandit 공식 심볼로지 설정 가이드는 Configure Barcode Symbologies (iOS)에서 확인할 수 있습니다.
Active Symbol Counts — 길이 제한으로 오인식·CPU 동시 절감
심볼로지를 하나로 좁혔다면 다음 단계는 해당 심볼로지 내에서 허용할 데이터 길이를 제한하는 것입니다. 이 설정이 SymbologySettings.activeSymbolCounts입니다.
EAN-13이나 UPC-A처럼 길이가 고정된 심볼로지에는 이 설정이 의미가 없습니다. 효과가 두드러지는 것은 Code 128, Code 39, Code 93처럼 가변 길이를 허용하는 심볼로지입니다. 이런 심볼로지에서는 디코더가 가능한 모든 길이에 대해 가설을 평가하므로, 허용 범위를 좁히면 그만큼 평가 경로가 줄어듭니다.
예를 들어, 제조 현장에서 작업 지시서에 붙는 내부 관리 코드가 항상 8자리 Code 39라면 activeSymbolCounts = Set([8])로 설정합니다. 7자리, 9자리, 10자리 Code 39는 인식 단계에서 즉시 폐기되어 콜백에 도달하지 않습니다. 오인식 가능성이 줄고 처리 경로도 단축됩니다.
이 설정은 SymbologySettings 객체에서 심볼로지별로 독립적으로 지정합니다. 심볼로지를 활성화하는 시점에 함께 설정하는 것이 코드를 명확히 유지하는 방법입니다.
iOS Swift — Code 39, 8자리만 허용
let settings = BarcodeCaptureSettings()
settings.set(symbology: .code39, enabled: true)
let c39 = settings.settings(for: .code39)
c39.activeSymbolCounts = Set([8])
Android Kotlin — Code 39, 8자리만 허용
val settings = BarcodeCaptureSettings()
settings.enableSymbology(Symbology.CODE39, true)
val c39 = settings.getSymbologySettings(Symbology.CODE39)
c39.activeSymbolCounts = setOf(8)
Web TypeScript — Code 39, 8자리만 허용
import { BarcodeCaptureSettings, Symbology } from "@scandit/web-datacapture-barcode";
const settings = new BarcodeCaptureSettings();
settings.enableSymbology(Symbology.Code39, true);
const c39 = settings.settingsForSymbology(Symbology.Code39);
c39.activeSymbolCounts = [8];
React Native — Code 39, 8자리만 허용
import { BarcodeCaptureSettings, Symbology } from "scandit-react-native-datacapture-barcode";
const settings = new BarcodeCaptureSettings();
settings.enableSymbology(Symbology.Code39, true);
const c39 = settings.settingsForSymbology(Symbology.Code39);
c39.activeSymbolCounts = [8];
activeSymbolCounts에 여러 값을 지정할 수도 있습니다. 예를 들어 6자리 또는 8자리 Code 39를 모두 허용해야 한다면 Set([6, 8])로 설정합니다. 범위가 넓을수록 처리 효율 절감 효과가 줄어들므로, 현장에서 실제로 사용하는 길이만 포함하는 것이 원칙입니다.
Web TypeScript — Active Symbol Counts 적용 전후 비교 (CPU 절감 효과)
import { BarcodeCaptureSettings, Symbology } from "@scandit/web-datacapture-barcode";
const settings = new BarcodeCaptureSettings();
// [적용 전] Code 128 활성화, 길이 제한 없음
// → 디코더가 모든 가능한 길이에 대해 가설 평가
// → 불필요한 오인식(예: 인접 라벨의 짧은 Code 128) 콜백 도달
settings.enableSymbology(Symbology.Code128, true);
// [적용 후] Code 128 + Active Symbol Counts 12자리 고정
// → 12자리가 아닌 Code 128 결과는 콜백 전 즉시 폐기
// → 프레임당 처리 단계 단축, CPU 사용량 감소
const symSettings = settings.settingsForSymbology(Symbology.Code128);
symSettings.activeSymbolCounts = [12]; // 국내 택배 운송장 12자리 고정
// 변경 후 BarcodeCapture에 적용
await barcodeCapture.applySettings(settings);
SymbologySettings API 전체 레퍼런스는 SymbologySettings API (iOS)에서 확인할 수 있습니다.
Composite Codes — 의약품·항공부품 환경의 필수 설정
Composite Code(복합 코드)는 1D 선형 심볼로지 위에 2D 컴포넌트(CC-A, CC-B, CC-C)가 수직으로 결합된 GS1 합성 심볼로지입니다. 국내 의약품 라벨, GS1-128 의약품 표준코드, 일부 항공부품 라벨에서 사용됩니다.
Composite Code를 인식하려면 BarcodeCaptureSettings의 enabledCompositeTypes 속성에 필요한 유형을 명시적으로 설정해야 합니다. 1D 심볼로지만 활성화해서는 2D 컴포넌트 데이터가 콜백에 포함되지 않습니다. CC-A는 최대 56비트, CC-B는 최대 338비트의 보조 데이터를 담을 수 있으며, 국내 의약품 표준코드에서는 CC-A와 CC-B가 주로 쓰입니다.
Composite Code 활성화의 트레이드오프는 분명합니다. 디코더가 매 프레임마다 1D 컴포넌트와 2D 컴포넌트를 동시에 탐색하므로 단순 1D 인식보다 처리 부담이 큽니다. 의약품 라인처럼 Composite Code가 반드시 필요한 환경에서만 활성화하고, 일반 리테일·물류 환경에서는 비활성화 상태를 유지하는 것이 권장 설정입니다.
Android Kotlin — GS1 의약품 Composite Code 활성화 (CC-A + GS1-128)
import com.scandit.datacapture.barcode.capture.BarcodeCaptureSettings
import com.scandit.datacapture.barcode.data.CompositeType
import com.scandit.datacapture.barcode.data.Symbology
val settings = BarcodeCaptureSettings()
// GS1-128 (Code 128 캐리어) 활성화
settings.enableSymbology(Symbology.CODE128, true)
// CC-A 컴포짓 타입 활성화: 국내 의약품 MFDS 단위 포장에 주로 사용
// CC-A: GTIN + 만료일(AI 17) + 배치번호(AI 10) 보조 데이터 포함
// 주의: 일반 물류·리테일 환경에서는 활성화 금지 (CPU 부담 증가)
settings.enabledCompositeTypes = setOf(CompositeType.A)
// CC-B까지 필요한 경우 (배치번호/시리얼 필드가 길 때)
// settings.enabledCompositeTypes = setOf(CompositeType.A, CompositeType.B)
한 국내 의약품 유통사의 GS1 DataMatrix + Composite Code 활성화 사례에서는, 비활성화 상태 대비 GTIN+만료일+배치번호를 단일 스캔으로 처리하는 처리량이 3.2배 향상되었습니다. 이는 Composite Code 비활성화 상태에서 GTIN, 만료일, 배치번호를 별도 입력하거나 수동으로 파싱하던 기존 워크플로 대비 효율 개선으로, Composite Code 활성화 자체의 CPU 부담보다 워크플로 단순화 효과가 훨씬 크다는 점을 보여줍니다.
이미지 프로세싱 — 해상도, 줌, 프레임 레이트 조정
이미지 프로세싱 설정은 인식 거리와 처리 효율 사이의 균형을 조절하는 영역입니다. 세 가지 주요 변수를 순서대로 살펴봅니다.
비디오 해상도 (videoResolution)
해상도는 인식 거리와 이미지 프로세싱 부하를 동시에 결정하는 가장 중요한 변수입니다. SCANDIT SDK에서는 CameraSettings의 preferredResolution 속성으로 제어합니다.
iOS Swift — 카메라 해상도 설정 (거리 vs. 배터리 트레이드오프)
import ScanditBarcodeCapture
// 원거리 바코드 인식이 필요한 경우: Full HD 설정
// 트레이드오프: 픽셀 수 2.25배 증가 → CPU/배터리 부담 증가
let cameraSettings = BarcodeCapture.recommendedCameraSettings
cameraSettings.preferredResolution = .fullHD // 1920×1080
// 핸드헬드 근거리 스캐닝: HD 설정으로 배터리 절약
// 30~60cm 이내 스캐닝에서는 HD로 충분한 경우가 많다
// cameraSettings.preferredResolution = .hD // 1280×720
let camera = Camera.default
camera?.apply(cameraSettings)
| 해상도 | 픽셀 수 | 인식 거리 | CPU 부하 | 권장 시나리오 |
|---|---|---|---|---|
| 480p (SD) | 854×480 | 가까운 거리 (<30cm) | 낮음 | 근거리 POS, 핸드헬드 리테일 |
| 720p (HD) | 1,280×720 | 중간 거리 (30~60cm) | 보통 | 일반 창고 피킹, 배송 앱 |
| 1080p (Full HD) | 1,920×1,080 | 먼 거리 (60cm~1m+) | 높음 | 컨베이어 고정 스캐너, 의약품 라인 |
| 4K (UHD) | 3,840×2,160 | 매우 먼 거리 (1m+) / 정밀 인식 / 손상된 작은 바코드 | 매우 높음 | 컨베이어 고정 카메라, 항공·의약품 라인 |
해상도 선택의 실무 원칙은 "필요한 최소 거리에서 동작하는 가장 낮은 해상도"입니다. 전원이 외부에서 공급되는 고정 스캐너라면 1080p를 선택해도 배터리 문제가 없지만, 배터리 의존 핸드헬드 단말기라면 720p에서 충분히 동작하는지 먼저 검증하고 1080p로 올립니다.
디지털 줌
스마트폰에는 광학 줌 기능이 없습니다. 디지털 줌은 이미지를 소프트웨어적으로 크롭·확대하는 방식이므로, 실제로는 픽셀 밀도가 낮아지는 효과입니다. 즉 디지털 줌을 2배로 적용하면 해상도를 절반으로 낮춘 것과 유사한 결과를 낳습니다. 원거리 바코드를 읽기 위해 디지털 줌을 사용하는 것은 역효과가 날 수 있습니다.
먼 거리 인식이 목적이라면 디지털 줌보다 해상도를 높이는 것이 더 안정적인 방법입니다. SCANDIT SDK는 CameraSettings.zoomFactor 속성을 제공하지만, 이 값을 높이면 동일 물리 면적에서 읽을 수 있는 픽셀이 줄어든다는 점을 인지해야 합니다.
프레임 레이트
SDK는 기본적으로 카메라 하드웨어 최대 fps로 동작합니다. 최신 스마트폰은 60fps, 일부는 120fps를 지원합니다. 그러나 스캔 대상이 빠르게 이동하지 않는 환경(핸드헬드 스캐닝, 느린 컨베이어)에서는 30fps로 제한해도 인식률 차이가 없습니다. 처리 프레임 수를 절반으로 줄이면 CPU 사용량이 거의 선형으로 감소합니다.
고속 컨베이어처럼 바코드가 빠르게 지나가는 환경에서는 높은 fps가 유효합니다. 바코드가 카메라 시야를 벗어나기 전에 충분한 프레임을 캡처해야 하기 때문입니다. 이 경우 60fps 이상을 유지하되 해상도를 낮추는 것이 처리 효율 면에서 유리한 트레이드오프가 될 수 있습니다.
조명·노출 — 어두운 환경·햇빛 반사·거리 변화 대응
조명 조건은 SDK 설정만으로 완전히 해결할 수 없는 물리적 제약이지만, SDK에서 제공하는 설정으로 상당 부분 보완할 수 있습니다.
카메라 토치 자동 활성화
SDK는 Camera에서 torch 모드를 설정할 수 있습니다. TorchState.auto로 설정하면 조도 센서 값에 따라 SDK가 자동으로 플래시를 켜고 끕니다. 국내 창고의 어두운 구석이나 야간 배송 환경에서 효과적입니다.
수동으로 torch를 제어하려면 TorchState.on / TorchState.off를 사용자 UI(버튼)에 연결하면 됩니다. 의약품 창고처럼 비반사 코팅이 된 표면에 토치가 반사를 일으켜 오히려 인식률이 떨어지는 경우, 수동 제어가 더 적합합니다.
Web TypeScript — 저조도 환경 카메라 토치 프로그래밍 제어
import { Camera, TorchState } from "@scandit/web-datacapture-core";
// 카메라 획득 후 조도 조건에 따라 토치 제어
const camera = Camera.default;
// 자동 모드: 조도 센서가 낮으면 SDK가 자동으로 토치 켬
await camera?.switchToDesiredTorchState(TorchState.Auto);
// 수동 토치 ON (버튼 UI에 연결)
// await camera?.switchToDesiredTorchState(TorchState.On);
// 수동 토치 OFF (반사 문제 발생 시)
// await camera?.switchToDesiredTorchState(TorchState.Off);
노출 보정 (Exposure Compensation)
카메라 자동 노출(AE)은 장면 전체의 평균 밝기를 기준으로 노출을 설정합니다. 바코드가 밝은 배경에 인쇄된 경우 AE가 충분히 노출을 높이지 않아 바코드가 과노출이나 저노출 상태로 찍히는 문제가 발생할 수 있습니다. CameraSettings.exposureCompensation 값을 조정하면 AE 기준값에서 상향/하향 보정이 가능합니다.
햇빛이 강한 실외 환경이나 광택 포장재에 반사광이 심한 경우에는 노출을 낮추고(-값), 어두운 창고에서는 높이는(+값) 방향으로 현장 테스트를 거쳐 최적값을 확정합니다.
형광등 플리커 대응
국내 창고에서 흔히 쓰이는 형광등(FL)은 한국 전력망 주파수 50Hz에 맞춰 밝기가 초당 100회 변동합니다. 카메라 노출 사이클(셔터 스피드)이 이 주기와 맞지 않으면 특정 프레임에서 이미지가 어둡게 찍혀 인식률이 급락합니다. 대응 방법은 두 가지입니다.
첫째, 셔터 스피드를 50Hz 배수로 맞춥니다. 1/50초(20ms) 또는 1/100초(10ms) 노출 시간을 설정하면 플리커 주기와 동기화되어 균일한 밝기의 프레임을 얻습니다.
둘째, 프레임 레이트를 25fps 또는 50fps로 제한합니다. 50Hz 플리커와 정수비가 되는 fps로 제한하면 플리커 영향을 받는 프레임 비율이 줄어듭니다.
AI 기반 최적화 (SDK 8)
SCANDIT SDK 8에서 도입된 AI 기반 기능은 기존 수동 설정으로는 해결하기 어려운 시나리오에서 의미 있는 효과를 냅니다. SDK 8에서 확인된 기능은 Scandit AI Engine(전체 인식 알고리즘 강화), Smart Duplicate Filter, 그리고 scanIntention 속성을 통한 의도 추론입니다. 공식 기능 목록은 Scandit Docs — AI-Powered Barcode Scanning을 참조하세요.
의도 추론 — scanIntention 속성 (SDK 8.1+)
SDK 8.1부터 BarcodeCaptureSettings의 scanIntention 속성이 기본값 ScanIntention.SMARTSELECTION으로 설정됩니다. 이 설정은 사용자가 스캔 완료 후 같은 바코드 위에 카메라를 계속 향하고 있을 때 의도하지 않은 반복 스캔을 방지합니다. SDK가 기기 움직임과 타이밍을 분석해 새로운 스캔 의도인지 단순 유지인지를 추론하고, 동일 바코드의 중복 콜백을 억제합니다.
주의: 밀집 선반에서 인접 바코드 중 특정 바코드를 선택하는 기능(다중 바코드 환경 피킹 정확도 향상)은 별도 제품인 MatrixScan Pick의 영역입니다. MatrixScan 제품 페이지를 참조하세요.
iOS Swift — scanIntention 속성 설정 (SDK 8.1+)
import ScanditBarcodeCapture
let settings = BarcodeCaptureSettings()
settings.set(symbology: .ean13UPCA, enabled: true)
// SDK 8.1+ 기본값: ScanIntention.SMARTSELECTION
// 동일 바코드의 의도하지 않은 반복 스캔을 방지합니다.
// 참조: https://docs.scandit.com/sdks/web/ai-powered-barcode-scanning/
settings.scanIntention = .smart
// .manual: 감지된 바코드를 즉시 콜백 (키오스크·고정 스캔 환경에 적합)
// settings.scanIntention = .manual
let barcodeCapture = BarcodeCapture(context: context, settings: settings)
한국 도메인 벤치마크
아래 수치는 데이터커넥트가 국내 구축 프로젝트에서 수집한 벤치마크 데이터를 익명화한 것입니다. 고객사 실명과 세부 시스템 정보는 포함하지 않으며, 수치는 해당 현장 조건에서의 측정값으로 모든 환경에 일반화되지 않을 수 있습니다.
택배 분류 라인 — 심볼로지 최소화 효과
한 국내 대형 택배사 자동 분류 라인에서 초기 구성(7개 심볼로지 활성화)과 최적화 구성(Code 128 단일 활성화)을 비교했습니다. 동일 하드웨어(고정형 카메라 스캐너, 1080p), 동일 컨베이어 속도 기준에서 분류 처리량이 분당 280회에서 480회 이상으로 증가했습니다. 심볼로지 수 감소가 디코드 레이턴시에 미치는 영향이 얼마나 직접적인지 보여주는 사례입니다.
이 변경에서 함께 적용한 설정은 하나뿐이었습니다. 불필요한 심볼로지를 enabled: false로 명시적으로 비활성화한 것이 전부입니다. 코드 변경 한 줄이 처리량을 70% 가까이 높인 사례로, 최적화에서 심볼로지 제한이 가장 먼저 해야 할 작업임을 다시 확인시켜 줍니다.
의약품 유통사 라인 — Composite Code + DataMatrix 활성화 효과
한 국내 의약품 유통사의 GS1 DataMatrix 처리 시스템에서 Composite Code 활성화 전후를 비교했습니다. 비활성화 상태에서는 GTIN, 만료일, 배치번호를 각각 별도 스캔 또는 수동 입력으로 처리했는데, DataMatrix + Composite Code 동시 활성화 후 단일 스캔으로 세 필드를 동시에 수집하게 되었습니다. 스캔당 처리 단계가 3단계에서 1단계로 줄면서 전체 처리량이 3.2배 향상되었습니다.
이 사례에서 주목할 점은, Composite Code 활성화로 CPU 부담은 증가했지만 워크플로 단순화 효과가 그것을 압도했다는 점입니다. 단일 설정 변경이 운영 비용(처리 시간 × 인건비)에 미치는 영향은 하드웨어 교체 없이 얻을 수 있는 가장 큰 개선 중 하나입니다.
노후 Android 단말기 — SDK 버전 업그레이드 효과
노후 Android 단말기 환경에서는 SDK 자체 업그레이드(SDK 7 → 8)만으로도 디코더 알고리즘 개선 효과를 볼 수 있습니다. 단 인식률 측정은 반드시 실제 운영 환경 라벨로 A/B 테스트해야 합니다.
사후 필터링은 별도 가이드
이 페이지는 스캔 엔진(decoder) 레벨의 성능 튜닝을 다룹니다. 심볼로지 활성화, Active Symbol Counts, Composite Code, 이미지 프로세싱, 조명·노출, AI 기반 기능까지 — 이 설정들은 모두 바코드가 인식되기 전(또는 인식되는 과정)에서 작동하는 사전 최적화입니다.
인식된 바코드를 어떻게 거를 것인가 — 정규식 패턴, 자릿수 제한, 시각적 마스킹, AI 중복 제거 — 는 별도의 5계층 필터링 설계 문제입니다. 본 페이지의 엔진 튜닝과 사후 필터링을 함께 적용할 때 가장 효율적인 스캔 파이프라인이 완성됩니다.
관련 심화 가이드: 사후 필터링 5계층은 필터링 가이드에서 별도로 다룹니다.
자주 묻는 질문
스캔 속도에 가장 큰 영향을 주는 설정은? 활성화된 심볼로지 수가 단일 변수 중 가장 직접적인 영향을 줍니다. 5개 심볼로지를 1개로 줄이면 프레임당 처리 시간이 30~60% 감소합니다. 그 다음 단계로 Active Symbol Counts를 적용해 가변 길이 심볼로지의 처리 범위를 좁히고, Composite Code는 필요한 경우에만 활성화합니다.
인식 거리를 늘리려면? 카메라 해상도를 높이는 것이 가장 안정적인 방법입니다. 720p → 1080p로 올리면 동일 거리에서 더 많은 픽셀로 바코드를 분석할 수 있습니다. 디지털 줌은 오히려 픽셀 밀도를 낮추므로 권장하지 않습니다.
Active Symbol Counts와 심볼로지 활성화 순서는? 심볼로지 활성화(Restrict Symbology)가 먼저입니다. 심볼로지가 비활성화 상태에서는 Active Symbol Counts 설정이 의미 없습니다. 올바른 순서는 필요한 심볼로지만 활성화 → 해당 심볼로지에서 허용할 자릿수 범위를 좁히는 것입니다.
저조도 환경에서 인식률이 떨어진다면? torch 모드를 auto로 설정해 자동 보조광을 활성화하고, 노출 보정 값을 상향 조정합니다. 국내 창고의 형광등 플리커가 원인이라면 셔터 스피드를 50Hz 배수(1/50초, 1/100초)로 맞추거나 프레임 레이트를 25fps/50fps로 제한해 플리커 영향을 줄입니다. SDK 8의 Scandit AI Engine은 인식 알고리즘 자체를 강화하지만, 저조도의 근본 해결은 보조광·노출 보정 등 하드웨어·카메라 설정에 있습니다.
Composite Code는 언제 활성화하나?
GS1 의약품 표준코드, 의료기기, 항공부품처럼 1D+2D 합성 코드가 명확히 필요한 환경에서만 enabledCompositeTypes를 설정합니다. 활성화하면 디코더 처리 부담이 증가하므로 일반 리테일·물류 환경에서는 비활성화를 유지합니다.
최근 업데이트
최근 업데이트: 2026-05-01
이 페이지는 SCANDIT SDK 8.x 기준으로 작성되었습니다. SDK 버전 업데이트에 따라 API 시그니처나 설정 방법이 변경될 수 있으며, 데이터커넥트는 분기별로 내용을 검토하고 업데이트합니다. SCANDIT SDK 스캔 성능 최적화 상담 및 현장 PoC 설계가 필요하시면 데이터커넥트 기술팀에 문의하거나 데모를 신청해 주시기 바랍니다.
참조 문서: Scandit Barcode Scanning Performance · Configure Barcode Symbologies (iOS) · SymbologySettings API (iOS)
코드 샘플
Restrict Symbology + Active Symbol Counts로 EAN-13 단일화 및 자릿수 제한
import ScanditBarcodeCapture
let settings = BarcodeCaptureSettings()
// EAN-13만 활성화 (사전 차단 = 가장 가벼움)
settings.set(symbology: .ean13UPCA, enabled: true)
// Code 39 사용 시 8자리만 처리 (오인식↓)
let c39 = settings.settings(for: .code39)
c39.activeSymbolCounts = Set([8])
Restrict Symbology + Active Symbol Counts로 EAN-13 단일화 및 자릿수 제한
val settings = BarcodeCaptureSettings()
settings.enableSymbology(Symbology.EAN13_UPCA, true)
val c39 = settings.getSymbologySettings(Symbology.CODE39)
c39.activeSymbolCounts = setOf(8)
Restrict Symbology + Active Symbol Counts로 EAN-13 단일화 및 자릿수 제한
import { BarcodeCaptureSettings, Symbology } from "@scandit/web-datacapture-barcode";
const settings = new BarcodeCaptureSettings();
settings.enableSymbology(Symbology.EAN13UPCA, true);
const c39 = settings.settingsForSymbology(Symbology.Code39);
c39.activeSymbolCounts = [8];
Restrict Symbology + Active Symbol Counts로 EAN-13 단일화 및 자릿수 제한
import { BarcodeCaptureSettings, Symbology } from "scandit-react-native-datacapture-barcode";
const settings = new BarcodeCaptureSettings();
settings.enableSymbology(Symbology.EAN13UPCA, true);
const c39 = settings.settingsForSymbology(Symbology.Code39);
c39.activeSymbolCounts = [8];

