이 페이지는 기계 번역을 사용하여 번역되었습니다. 영어 원문을 보려면 여기를 클릭하십시오.
실시간 이미지 수집 중 알약 내 이상 감지
R2026b이 예제는 실시간 이미지 수집 중에 알약 내 이상을 감지하는 방법을 보여줍니다. 이 예제에서는 Detect Image Anomalies Using Explainable FCDD Network (Visual Inspection Toolbox)에서 제공된 사전 학습된 신경망을 수정합니다.
먼저 이미지 수집 하드웨어를 사용하여 정상 알약과 이상이 있는 알약의 이미지로 구성된 데이터 세트를 생성합니다. 그런 다음, 이 데이터 세트를 사용하여 사전 학습된 신경망을 보정하고 테스트합니다.
다음으로, 알약의 실시간 이미지를 촬영하고, 훈련된 이상 감지기를 사용하여 해당 알약이 정상인지 이상인지 분류합니다. 실시간 이미지 미리보기에는 각 픽셀이 정상인지 이상인지에 대한 확률을 나타내는 텍스트 레이블도 표시됩니다.
마지막으로, MATLAB® Compiler™를 사용하여 훈련된 이상 감지 모델을 배포하고 실시간 이미지 수집을 수행합니다. 스크립트가 독립 실행형 프로그램으로 배포되면, MATLAB 라이선스가 없는 어떤 컴퓨터에서든 이를 실행할 수 있습니다.
이 예제에서는 보정, 테스트 및 실시간 알약 이미지 분류에 사용할 알약 이미지를 촬영하기 위해 웹캠을 사용합니다. 하지만 Image Acquisition Toolbox™에서 지원하는 모든 이미지 수집 하드웨어를 사용하여 이 예제를 실행할 수 있습니다.
이 예제를 실행하려면 필수 MATLAB 툴박스 외에도 다음 애드온이 설치되어 있어야 합니다.
Image Acquisition Toolbox Support Package for OS Generic Video Interface
Visual Inspection Toolbox™
사전 학습된 신경망 다운로드
이 예제에서는 알약의 이상 감지를 위해 훈련된 사전 학습된 신경망을 사용합니다. 이 신경망을 다운로드하십시오.
trainedPillAnomalyDetectorNet_url = ... "https://ssd.mathworks.com/supportfiles/vision/data/trainedFCDDPillAnomalyDetectorSpkg.zip"; downloadTrainedNetwork(trainedPillAnomalyDetectorNet_url,pwd); net = load(fullfile(pwd,"folderForSupportFilesInceptionModel","trainedPillFCDDNet.mat")); detector = net.detector;
보정 및 테스트를 위한 데이터 세트 준비
사전 학습된 알약 이상 감지기를 사용하는 이유는, 이 탐지기를 학습하는 데 사용된 이미지가 이 예제에서 촬영 및 분류된 이미지와 유사하기 때문입니다. 기존 모델을 처음부터 다시 학습시키는 대신, 보정 및 테스트를 위해 이미지를 수집합니다. 워크플로상 다른 용도의 육안 검사 모델이 필요한 경우, 모델을 처음부터 훈련하는 방법에 대한 자세한 내용은 Detect Image Anomalies Using Explainable FCDD Network (Visual Inspection Toolbox)를 참조하십시오.
이미지 수집 하드웨어 설정
videoinput 함수를 사용하여 카메라에 연결하고 해당 속성을 지정하십시오. 이 예제에서는 OS의 일반 비디오 인터페이스를 사용하여 YUV2_352x288 비디오 형식으로 Logitech® 웹캠에서 이미지를 가져옵니다.
vid = videoinput("winvideo","1","YUY2_352x288"); vid.ReturnedColorSpace = 'rgb'; vid.FramesPerTrigger = 70;
videoinput 객체의 소스 속성을 가져옵니다. 최적의 이미지 데이터 수집을 위해 장치별 속성을 지정합니다. 이러한 속성에 지정하는 값은 카메라 하드웨어와 이미지를 촬영하는 주변 환경에 따라 달라집니다.
src = getselectedsource(vid);
데이터 수집하기
이미지 수집 하드웨어를 설치하고 설정을 마친 후에는 이미지를 수집할 수 있습니다. 즉시 수집 모드에서 데이터를 수집합니다. 트리거 유형에 대한 자세한 내용은 Specifying the Trigger Type를 참조하십시오.
start(vid); wait(vid);
이미지 캡처를 마친 후, 수집한 이미지 프레임을 MATLAB 작업 공간에 저장하고, imwrite를 사용하여 해당 프레임을 TIF 파일로 저장하십시오.
img = getdata(vid,70); for f=1:vid.FramesAcquired imwrite(img(:,:,:,f), "image"+f+".tif"); end delete(vid);
현재 작업 디렉터리에서 ImageData라는 이름의 폴더를 만드십시오. 이 폴더 안에 normal와 dirt라는 이름의 새 폴더 두 개를 만들고, 각각 정상 알약과 이상 알약의 이미지를 해당 폴더로 이동시키십시오.
이 예제에서 사용된 원본 데이터 세트에는 정상 이미지 40장과 이물질 이미지 30장이 포함되어 있었습니다.
이 두 이미지는 각 클래스의 예시를 보여줍니다. 왼쪽에는 결함이 없는 정상적인 알약이 있고, 오른쪽에는 이물질이 섞인 알약이 있습니다. 이 이미지들의 속성은 Detect Image Anomalies Using Explainable FCDD Network (Visual Inspection Toolbox) 예제의 훈련 데이터 세트의 속성과 매우 유사합니다.

데이터를 불러오고 전처리하기
정상 이미지 클래스와 이물질 이미지 클래스 모두에서 가져온 이미지 파일 모음을 관리하기 위해 i mageDataStore 객체인 imds를 생성합니다.
imageDir = fullfile(pwd,"ImageData"); imds = imageDatastore(imageDir,IncludeSubfolders=true,LabelSource="foldernames");
imds를 교정 세트와 테스트 세트(각각 imdsCal와 imdsTest)로 나눕니다. 보정용 이미지는 분류기의 임계값을 결정하는 데 사용됩니다. 이 분류기는 임계값을 초과하는 이상 점수를 가진 이미지를 ‘이상’으로 레이블링합니다. 나머지 이미지는 테스트용이며, 분류기를 평가하는 데 사용됩니다.
normalTrainRatio = 0; anomalyTrainRatio = 0; normalCalRatio = 0.70; anomalyCalRatio = 0.60; normalTestRatio = 1 - (normalTrainRatio + normalCalRatio); anomalyTestRatio = 1 - (anomalyTrainRatio + anomalyCalRatio); rng(0); [imdsTrain,imdsCal,imdsTest] = splitAnomalyData(imds,["dirt"],... NormalLabelsRatio=[normalTrainRatio normalCalRatio normalTestRatio],... AnomalyLabelsRatio=[anomalyTrainRatio anomalyCalRatio anomalyTestRatio]);
Splitting anomaly dataset
-------------------------
* Finalizing... Done.
* Number of files and proportions per class in all the datasets:
Input Train Validation Test
NumFiles Ratio NumFiles Ratio NumFiles Ratio NumFiles Ratio
_____________________________ _________________ _____________________________ _________________
dirt 30 0.428571428571429 0 0 18 0.391304347826087 12 0.5
normal 40 0.571428571428571 0 0 28 0.608695652173913 12 0.5
addLabelData 헬퍼 함수에서 지정한 연산을 사용하여 transform 함수를 호출함으로써, 보정 데이터 세트와 테스트 데이터 세트 모두에 포함된 normal 및 dirt 이미지에 이진 레이블을 추가합니다.
dsCal = transform(imdsCal,@addLabelData,IncludeInfo=true); dsTest = transform(imdsTest,@addLabelData,IncludeInfo=true);
정상 이미지와 이상 이미지가 모두 포함된 보정 데이터 샘플을 시각화해 보십시오.
numObs = length(imdsCal.Labels); idx = randperm(numObs,9); montage(imdsCal,Indices=idx)

분류 모델 보정 및 테스트
이상 임계값 선택하기
보정 데이터 세트를 사용하여 이상 감지기의 이상 점수 임계값을 선택하십시오. 이 감지기는 이미지의 점수가 임계값보다 높은지 낮은지에 따라 이미지를 분류합니다. 임계값을 결정하기 위해 정상 이미지와 이상 이미지를 모두 사용합니다.
보정 세트에 포함된 각 이미지에 대해 평균 이상 점수와 정답 레이블을 구한 다음, 점수의 히스토그램을 그립니다.
scores = predict(detector,dsCal); labels = imdsCal.Labels ~= "normal"; numBins = 20; [~,edges] = histcounts(scores,numBins); figure hold on hNormal = histogram(scores(labels==0),edges); hAnomaly = histogram(scores(labels==1),edges); hold off legend([hNormal,hAnomaly],"Normal","Anomaly") xlabel("Mean Anomaly Score") ylabel("Counts")

anomalyThreshold (Visual Inspection Toolbox) 함수를 사용하여 최적의 이상 임계값을 계산합니다. 보정 데이터 세트에 대해 처음 두 개 입력 인수를 ground truth 레이블 labels와 예측 이상 점수 scores로 지정합니다. 세 번째 입력 인수는 true로 지정합니다. 참양성 이상 이미지는 labels 값이 true이기 때문입니다.
thresh = anomalyThreshold(labels,scores,true);
이상 감지기의 Threshold 속성을 최적 값으로 설정합니다.
detector.Threshold = thresh;
분류 모델 평가하기
이상 감지기 detector를 사용하여 테스트 세트의 각 이미지를 정상 또는 이상으로 분류하십시오.
testSetOutputLabels = classify(detector,dsTest);
각 테스트 이미지의 ground truth 레이블을 가져옵니다.
testSetTargetLabels = dsTest.UnderlyingDatastores{1}.Labels;evaluateAnomalyDetection (Visual Inspection Toolbox) 함수를 사용하여 메트릭을 계산함으로써 이상 감지기를 평가하십시오. 이 함수는 테스트 데이터 세트에 대해 감지기의 정확도, 정밀도, 민감도, 특이도를 평가하는 몇몇 메트릭을 계산합니다.
metrics = evaluateAnomalyDetection(testSetOutputLabels,testSetTargetLabels,"dirt"); Evaluating anomaly detection results
------------------------------------
* Finalizing... Done.
* Data set metrics:
GlobalAccuracy MeanAccuracy Precision Recall Specificity F1Score FalsePositiveRate FalseNegativeRate
______________ ____________ _________ ______ ___________ _______ _________________ _________________
1 1 1 1 1 1 0 0
metrics의 ConfusionMatrix 속성은 테스트 세트에 대한 혼동행렬을 포함합니다. 혼동행렬을 추출하고 혼동 플롯을 표시합니다. 선택된 이상 임계값을 적용하여 재보정된 모델은 거짓 양성과 거짓 음성이 매우 적습니다.
M = metrics.ConfusionMatrix{:,:};
confusionchart(M,["Normal","Anomaly"])
acc = sum(diag(M)) / sum(M,"all");
title("Accuracy: "+acc)
설명 가능한 분류 결정에 대한 자세한 내용은 Detect Image Anomalies Using Explainable FCDD Network (Visual Inspection Toolbox) 예제를 참조하십시오.
이 감지기를 MAT 파일로 저장하여 나중에 MATLAB 또는 배포 워크플로에서 사용할 수 있도록 하십시오.
save('livePillDetector.mat','detector')
알약의 실시간 이미지 분류
카메라에서 제공하는 사용자 지정 이미지 미리보기를 활용하여 알약이 정상인지 이상인지에 대한 실시간 분류 결과를 표시할 수 있습니다. 이 섹션에서는 실시간 이미지를 처리하고, 개별 알약을 식별하며, 각 알약을 분류하고, 카메라 미리보기 이미지에 분류 결과를 오버레이하여 표시하기 위한 사용자 지정 미리보기 콜백 함수를 만드는 방법을 설명합니다. 이 섹션의 코드와 이 예제에 첨부된 업데이트 미리보기 콜백 함수는 보조 파일에서 확인할 수 있습니다.
videoinput 인터페이스를 사용하여 웹캠으로 1280×720 해상도의 이미지를 캡처합니다. 그런 다음, 알약이 원형이기 때문에 사용자 지정 미리보기 업데이트 콜백 함수를 사용하여 imfindcircles 함수를 통해 각 알약을 식별합니다. 각 알약 주변의 카메라 이미지를 잘라내고 감지기로 전달하여 분류를 수행합니다. 분류 결과에 따라 각 알약에 정상인지 이상인지 여부를 나타내는 레이블을 표시하십시오. 미리보기 창에서 정상 알약에는 Good 레이블이, 이상 알약에는 Bad 레이블이 부착됩니다.
이상 감지기를 불러옵니다.
load('livePillDetector.mat');웹캠에 연결하고 장치별 속성에 적절한 값을 지정합니다. 다음의 장치별 속성 값은 본 예제에서 원래 사용되었던 이 하드웨어 구성에 최적화되어 있습니다. 사용자의 환경에 따라 다른 설정이 필요할 수 있습니다.
vid = videoinput('winvideo',1,'YUY2_1280x720'); vid.ReturnedColorSpace = "rgb"; nBands = vid.NumberOfBands; vidRes = vid.ROIPosition; imWidth = vidRes(3); imHeight = vidRes(4); src = getselectedsource(vid); src.ExposureMode = "manual"; src.Exposure = -11; src.FocusMode = "manual"; src.Focus = 11; src.WhiteBalanceMode = "manual"; src.WhiteBalance = 2800; src.FrameRate = "20.0000";
Figure 창을 생성하고, Figure 내에 좌표축을 만듭니다. 그런 다음 비디오 미리보기 데이터를 표시할 이미지 객체를 생성합니다. 이미지 객체의 크기는 비디오 프레임의 크기와 일치해야 합니다. 이미지에 스크롤 패널을 추가합니다.
hFig = uifigure('Toolbar','none',... 'Menubar', 'none',... 'NumberTitle','Off',... 'AutoResizeChildren','Off',... 'Name','Live Pill Classification'); hAxis = uiaxes(hFig); disableDefaultInteractivity(hAxis); hImage = image(zeros(imHeight, imWidth, nBands),'Parent',hAxis); imscrollpanel(hFig,hImage);
업데이트 미리보기 창의 콜백 함수와 감지기를 이미지 객체의 애플리케이션 정의 데이터로 구성합니다. mypreview_fcn 콜백 함수를 정의하려면 “미리보기 데이터에 대한 사용자 지정 처리 수행” 섹션을 참조하십시오.
setappdata(hImage,'UpdatePreviewWindowFcn',@mypreview_fcn); setappdata(hImage,'Detector',detector);
사용자 지정 Figure 창에서 비디오 데이터를 미리 봅니다.
preview(vid,hImage);

미리보기 데이터에 대한 사용자 지정 처리 수행
각 프레임을 처리하여 알약이 정상인지, 아니면 이물질인지 판별하는 mypreview_fcn라는 콜백 함수를 생성하십시오. preview 함수를 호출하면, 수집된 각 프레임에 대해 이 콜백 함수가 호출됩니다.
mypreview_fcn 콜백 함수는 다음과 같은 작업을 수행합니다:
캡처된 각 프레임을 처리하고,
imfindcircles를 사용하여 그 안에 포함된 원의 개수를 파악합니다. 알약은 원형이기 때문에,imfindcircles함수는 지정된 반지름 범위를 바탕으로 알약의 개수를 파악합니다. 캡처한 이미지에서 ‘거리’ 툴을 사용하여 알약의 반지름을 픽셀 단위로 측정함으로써 반지름 범위를 결정합니다. 거리 툴의 사용 방법에 대한 자세한 내용은 영상 뷰어 앱을 사용하여 거리와 면적 측정하기를 참조하십시오.감지된 각 원을 중심으로 이미지를 자르고, 자른 이미지를 분류기로 전달하여 분류를 수행합니다.
분류 결정 결과에 따라 각 원의 중앙에
Good또는Bad라고 표시하는 텍스트 레이블을 추가합니다.감지된 모든 원에 대해 자르기 및 레이블 지정 단계를 반복합니다.
사용자 지정 미리보기 창의 이미지를 새로 고칩니다.
function mypreview_fcn(obj,event,hImage) persistent detector; persistent ImgSize; if isempty(detector) && isempty(ImgSize) % Anomaly detector detector = getappdata(hImage,'Detector'); % Width and height of images used during calibration ImgSize = [352 288]; end % Find circles (pills) in the current image frame img = event.Data; radiusRange = [30 80]; circles = imfindcircles(img,radiusRange); % Use classifier if circles are found if ~isempty(circles) % Loop through all circles for i = 1:size(circles,1) % Crop image around the circle (pill) % [pos1, pos2] - top-left corner pixel position % ImgSize - width and height from [pos1, pos2] pos1 = max(circles(i,1)-ImgSize(1)/2,0); pos2 = max(circles(i,2)-ImgSize(2)/2,0); croppedImage = imcrop(img,[pos1, pos2,ImgSize(1),ImgSize(2)]); if ~isempty(croppedImage) % Classify cropped image and assign a text label in the % center of the circle decision = classify(detector, croppedImage); if decision img = insertText(img,circles(i,:),"Bad", TextColor="Red",FontSize=14); else img = insertText(img,circles(i,:),"Good", TextColor="Green",FontSize=14); end end end end hImage.CData = img; end
카메라의 시야 내에 알약이 하나만 포함되어 있다면, 이 코드는 이미지를 올바르게 분류할 것으로 예상됩니다. 시야 내에 여러 알약이 포함된 경우, 잘린 이미지 하나에 알약이 하나 이상 포함되지 않도록 알약들 사이의 간격을 충분히 넓게 유지해야 합니다.
라이브 이미지 분류 기능을 독립형 애플리케이션으로 배포하기
독립 실행형 애플리케이션 컴파일러 (MATLAB Compiler) 앱을 사용하여 알약의 실시간 이미지 분류 기능을 독립형 애플리케이션으로 배포할 수 있습니다. MATLAB Compiler에 대한 라이선스가 있어야 합니다. 독립형 애플리케이션을 생성하면, 별도의 MATLAB 라이선스 없이도 여러 대의 컴퓨터에 배포할 수 있습니다.
독립 실행형 애플리케이션을 생성하려면 Application Compiler 앱에서 다음 단계를 수행해야 합니다.
customGUIForLiveClassification.m를 프로젝트의 메인 파일로 추가하십시오.권장 지원 패키지 목록에서 Image Acquisition Toolbox™ Support Package for OS Generic Video Interface와 Visual Inspection Toolbox™ 를 추가하십시오.
참고 항목
videoinput | getdata | imwrite | imageDatastore | imfindcircles