%save_code%
imds = imageDatastore('C:\Users\KDH\Downloads\dataset_folder', ...
'IncludeSubfolders', true, ...
'LabelSource', 'foldernames');
% 2. 학습/검증 데이터 분리 (80% 학습, 20% 검증)
[imdsTrain, imdsValidation] = splitEachLabel(imds, 0.8, 'randomized');
% 3. 사전학습된 SqueezeNet 불러오기
net = squeezenet;
lgraph = layerGraph(net);
% 4. 클래스 수에 맞게 마지막 레이어 교체
numClasses = numel(categories(imdsTrain.Labels));
newConvLayer = convolution2dLayer(1, numClasses, ...
'Name','new_conv', ...
'WeightLearnRateFactor',10, ...
'BiasLearnRateFactor',10);
newClassLayer = classificationLayer('Name','new_classoutput');
lgraph = replaceLayer(lgraph, 'conv10', newConvLayer);
lgraph = replaceLayer(lgraph, 'ClassificationLayer_predictions', newClassLayer);
% 5. 데이터 증강 설정
imageAugmenter = imageDataAugmenter( ...
'RandRotation',[-10 10], ...
'RandXTranslation',[-5 5], ...
'RandYTranslation',[-5 5], ...
'RandXScale',[0.9 1.1], ...
'RandYScale',[0.9 1.1]);
inputSize = net.Layers(1).InputSize;
augimdsTrain = augmentedImageDatastore(inputSize(1:2), imdsTrain, ...
'DataAugmentation', imageAugmenter, ...
'ColorPreprocessing','gray2rgb');
augimdsValidation = augmentedImageDatastore(inputSize(1:2), imdsValidation, ...
'ColorPreprocessing','gray2rgb');
% 6. 학습 옵션 설정
options = trainingOptions('sgdm', ...
'MiniBatchSize',16, ... % 미니 배치 사이즈 조절
'MaxEpochs',20, ... % 에폭 증가
'InitialLearnRate',1e-4, ...
'Shuffle','every-epoch', ...
'ValidationData',augimdsValidation, ... % 검증 데이터 추가
'ValidationFrequency',30, ...
'Verbose',false, ...
'Plots','training-progress');
% 7. 학습 시작
trainedNet = trainNetwork(augimdsTrain, lgraph, options);
% 8. 학습된 모델 저장
save('trainedRecycleNet.mat','trainedNet');
disp('학습 완료. 모델이 저장되었습니다.');
% 9. 검증 정확도 출력
predLabels = classify(trainedNet, augimdsValidation);
valLabels = imdsValidation.Labels;
accuracy = sum(predLabels == valLabels)/numel(valLabels);
fprintf('검증 정확도: %.2f%%\n', accuracy * 100);
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
%cam_code%
% trainedRecycleNet.mat 파일에서 trainedNet 로드
load('trainedRecycleNet.mat','trainedNet');
% 1. 웹캠 객체 생성 및 이미지 스냅샷
cam = [];
arduino = [];
try
cam = webcam;
disp('웹캠이 성공적으로 연결되었습니다.');
% 웹캠에서 단일 이미지 스냅샷 찍기
disp('웹캠에서 이미지 한 장을 가져오는 중...');
img = snapshot(cam);
disp('이미지를 성공적으로 가져왔습니다.');
% 가져온 이미지 표시
figure;
imshow(img);
title('웹캠에서 가져온 이미지');
% 2. 이미지 크기 조정 및 분류
imgResized = imresize(img, trainedNet.Layers(1).InputSize(1:2));
% 이미지 분류
[label, scores] = classify(trainedNet, imgResized);
% 클래스 이름 목록 가져오기
classNames = trainedNet.Layers(end).Classes;
% 3. 확률 차이 기반 분류 로직 추가
[sortedScores, sortedIdx] = sort(scores, 'descend');
predictedLabel = string(label); % 초기 예측 라벨
% 가장 높은 두 확률의 차이 계산
threshold_diff = 0.10;
% 일반 쓰레기로 분류할 클래스 이름 지정
generalWasteClassName = 'GeneralWaste';
if (sortedScores(1) - sortedScores(2)) < threshold_diff
predictedLabel = generalWasteClassName;
end
% 4. 결과 출력
disp("=====================================");
disp("웹캠 이미지 분류 결과:");
disp("최종 예측 라벨: " + predictedLabel); % 수정된 예측 라벨 출력
disp("클래스별 확률:");
for i = 1:numel(classNames)
fprintf(" %s: %.4f\n", string(classNames(i)), scores(i));
end
title("최종 예측 라벨: " + predictedLabel);
% 5. 아두이노 통신 로직
disp("아두이노로 보낼 신호: " + predictedLabel);
arduino = serialport("COM7", 9600);
pause(2); % 연결 안정화 시간
if predictedLabel == "plastic"
write(arduino, "P", "char");
disp("Sent 'P' for plastic.");
elseif predictedLabel == "can"
write(arduino, "C", "char");
disp("Sent 'C' for bottle.");
elseif predictedLabel == "Glass"
write(arduino, "G", "char");
disp("Sent 'G' for glass.");
elseif predictedLabel == generalWasteClassName
write(arduino, "N", "char");
disp("Sent 'N' for general waste.");
end
pause(2); % 전송 후 안정화 시간
catch ME
% 오류 발생 시 메시지 출력
if strcmp(ME.identifier, 'MATLAB:webcam:NoCamerasFound')
disp('오류: 시스템에서 웹캠을 찾을 수 없습니다. 웹캠이 연결되어 있는지 확인해주세요.');
elseif strcmp(ME.identifier, 'MATLAB:webcam:DeviceAlreadyInUse')
disp('오류: 웹캠이 다른 프로그램에서 이미 사용 중입니다. 다른 웹캠을 사용하는 프로그램을 모두 종료해주세요.');
elseif contains(ME.message, 'serialport') || contains(ME.message, 'COM')
disp('오류: 아두이노 시리얼 통신 문제. COM 포트, 보드레이트, 또는 아두이노 연결 상태를 확인해주세요.');
fprintf(2, '자세한 오류 메시지: %s\n', ME.message);
else
disp(['알 수 없는 오류가 발생했습니다: ' ME.message]);
disp('웹캠 드라이버, 권한, 연결 상태 또는 MATLAB 경로 설정을 확인해보세요.');
end
finally
% 웹캠 객체 정리
if exist('cam', 'var') && isvalid(cam)
clear cam;
disp('웹캠 객체를 정리했습니다.');
end
% 아두이노 시리얼 포트 객체 닫기 및 정리
if ~isempty(arduino) && isvalid(arduino)
clear arduino; % serialport 객체 정리
disp('Serial port closed and cleared.');
end
end
引用
동휘 (2026). wecycling(save_code, cam_code) (https://github.com/kdh030405/wecycling), GitHub. に取得済み.
MATLAB リリースの互換性
作成:
R2025a
すべてのリリースと互換性あり
プラットフォームの互換性
Windows macOS Linuxタグ
GitHub の既定のブランチを使用するバージョンはダウンロードできません
| バージョン | 公開済み | リリース ノート | |
|---|---|---|---|
| 1.0.1 | save_code, cam_code 포함 |
|
|
| 1.0.0 |
|
この GitHub アドオンでの問題を表示または報告するには、GitHub リポジトリにアクセスしてください。
この GitHub アドオンでの問題を表示または報告するには、GitHub リポジトリにアクセスしてください。
