Klasifikasi Jenis Buah Menggunakan Linear Discriminant Analysis
Linear Discriminant Analysis (LDA) merupakan salah satu metode yang digunakan untuk mengelompokkan data ke dalam beberapa kelas. Penentuan pengelompokan didasarkan pada garis batas (garis lurus) yang diperoleh dari persamaan linear.
Berikut ini merupakan contoh aplikasi pengolahan citra untuk mengklasifikasikan jenis buah menggunakan linear discriminant analysis. Jenis buah yang diklasifikasikan adalah buah apel dan buah jeruk. Kedua jenis buah tersebut dibedakan berdasarkan ciri warnanya menggunakan nilai hue dan saturation. Contoh citra buah pada masing-masing kelas ditunjukkan pada gambar di bawah ini.

Algoritma dan pemrograman matlab untuk klasifikasi jenis buah adalah sebagai berikut:
1. Proses pelatihan
a. Membaca citra pada data latih (terdiri dari 15 citra apel dan 10 citra jeruk)
b. Melakukan transformasi ruang warna dari citra rgb menjadi citra L*a*b
c. Melakukan segmentasi citra menggunakan metode thresholding
d. Melakukan operasi morfologi untuk menyempurnakan hasil segmentasi
e. Melakukan transformasi ruang warna dari citra rgb menjadi citra HSV
f. Melakukan ekstraksi ciri warna berdasarkan nilai hue dan saturation
g. Mengimplementasikan linear discriminant analysis untuk klasifikasi
h. Melakukan plotting sebaran data pada masing-masing kelas
Source code yang digunakan untuk proses pelatihan adalah
clc; clear; close all; %%% Pelatihan % menetapkan lokasi folder data latih nama_folder = 'data latih'; % membaca nama file yang berformat jpg nama_file = dir(fullfile(nama_folder,'*.jpg')); % menghitung jumlah file yang dibaca jumlah_file = numel(nama_file); % menginisialisasi variabel ciri_h, ciri_s, dan kelas_buah ciri_h = zeros(jumlah_file,1); ciri_s = zeros(jumlah_file,1); kelas_buah = cell(jumlah_file,1); % melakukan ekstraksi ciri terhadap seluruh file yang dibaca for n = 1:jumlah_file % membaca file citra Img = imread(fullfile(nama_folder,nama_file(n).name)); % mengkonversi ruang warna citra rgb menjadi L*a*b cform = makecform('srgb2lab'); lab = applycform(Img,cform); % mengekstrak komponen b dari citra L*a*b b = lab(:,:,2); % melakukan thresholding terhadap komponen b bw = b>140; % melakukan operasi morfologi untuk menyempurnakan hasil segmentasi bw = imfill(bw,'holes'); % mengkonversi ruang warna citra rgb menjadi hsv hsv = rgb2hsv(Img); % mengekstrak komponen h dan s h = hsv(:,:,1); s = hsv(:,:,2); % mengubah nilai background menjadi nol h(~bw) = 0; s(~bw) = 0; % menghitung rata-rata nilai hue dan saturation ciri_h(n) = mean(h); ciri_s(n) = mean(s); end % menetapkan kelas target latih for n = 1:15 kelas_buah{n} = 'apel'; end for n = 16:jumlah_file kelas_buah{n} = 'jeruk'; end % menampilkan sebaran data latih figure; h1 = gscatter(ciri_h,ciri_s,kelas_buah,'rb','v^',[],'off'); set(h1,'LineWidth',2) axis([0 0.6 0 0.6]) xlabel('hue') ylabel('saturation') legend('apel (latih)','jeruk (latih)','Location','SE') title('{\bf Sebaran data latih}') % menentukan garis batas berdasarkan penghitungan linear discriminant % analysis figure; h1 = gscatter(ciri_h,ciri_s,kelas_buah,'rb','v^',[],'off'); set(h1,'LineWidth',2) xlabel('hue') ylabel('saturation') [X,Y] = meshgrid(linspace(0,0.6),linspace(0,0.6)); X = X(:); Y = Y(:); [C,err,P,logp,coeff] = classify([X Y],[ciri_h,ciri_s],... kelas_buah,'Linear'); hold on; gscatter(X,Y,C,'rb','.',1,'off'); K = coeff(1,2).const; L = coeff(1,2).linear; f = @(x,y) K + [x y]*L; h2 = ezplot(f,[0 0.6 0 0.6]); set(h2,'Color','y','LineWidth',2) axis([0 0.6 0 0.6]) xlabel('hue') ylabel('saturation') legend('apel (latih)','jeruk (latih)','daerah apel (latih)',... 'daerah jeruk (latih)','garis batas','Location','SE') title('{\bf Klasifikasi buah apel dan jeruk (pelatihan)}') % melakukan fitting linear discriminant analysis obj = fitcdiscr([ciri_h,ciri_s],kelas_buah); % menyimpan variabel obj save obj obj % menampilkan sebaran data latih dan data uji figure; h1 = gscatter(ciri_h,ciri_s,kelas_buah,'rb','v^',[],'off'); set(h1,'LineWidth',2) xlabel('hue') ylabel('saturation') [X,Y] = meshgrid(linspace(0,0.6),linspace(0,0.6)); X = X(:); Y = Y(:); [C,err,P,logp,coeff] = classify([X Y],[ciri_h,ciri_s],... kelas_buah,'Linear'); hold on; gscatter(X,Y,C,'rb','.',1,'off'); K = coeff(1,2).const; L = coeff(1,2).linear; f = @(x,y) K + [x y]*L; h2 = ezplot(f,[0 0.6 0 0.6]); set(h2,'Color','y','LineWidth',2) axis([0 0.6 0 0.6])
Grafik sebaran data latih pada masing-masing kelas ditunjukkan pada gambar berikut:

Sedangkan grafik sebaran data latih pada masing-masing kelas beserta garis batas yang dihasilkan ditunjukkan pada gambar berikut

2. Proses pengujian
a. Membaca citra pada data uji (terdiri dari 7 citra apel dan 8 citra jeruk)
b. Melakukan transformasi ruang warna dari citra rgb menjadi citra L*a*b
c. Melakukan segmentasi citra menggunakan metode thresholding
d. Melakukan operasi morfologi untuk menyempurnakan hasil segmentasi
e. Melakukan transformasi ruang warna dari citra rgb menjadi citra HSV
f. Melakukan ekstraksi ciri warna berdasarkan nilai hue dan saturation
g. Mengujikan data uji sesuai dengan garis batas yang terbentuk
h. Melakukan plotting sebaran data pada masing-masing kelas
Source code yang digunakan untuk proses pengujian adalah
%%% Pengujian % menetapkan lokasi folder data uji nama_folder = 'data uji'; % membaca nama file yang berformat jpg nama_file = dir(fullfile(nama_folder,'*.jpg')); % menghitung jumlah file yang dibaca jumlah_file = numel(nama_file); % menginisialisasi variabel ciri_h, ciri_s, dan kelas_buah ciri_h = zeros(jumlah_file,1); ciri_s = zeros(jumlah_file,1); kelas_buah = cell(jumlah_file,1); % melakukan ekstraksi ciri terhadap seluruh file yang dibaca for n = 1:jumlah_file % membaca file citra Img = imread(fullfile(nama_folder,nama_file(n).name)); % mengkonversi ruang warna citra rgb menjadi L*a*b cform = makecform('srgb2lab'); lab = applycform(Img,cform); % mengekstrak komponen b dari citra L*a*b b = lab(:,:,2); % melakukan thresholding terhadap komponen b bw = b>140; % melakukan operasi morfologi untuk menyempurnakan hasil segmentasi bw = imfill(bw,'holes'); % mengkonversi ruang warna citra rgb menjadi hsv hsv = rgb2hsv(Img); % mengekstrak komponen h dan s h = hsv(:,:,1); s = hsv(:,:,2); % mengubah nilai background menjadi nol h(~bw) = 0; s(~bw) = 0; % menghitung rata-rata nilai hue dan saturation ciri_h(n) = mean(h); ciri_s(n) = mean(s); end % menetapkan kelas target uji for n = 1:7 kelas_buah{n} = 'apel'; end for n = 8:jumlah_file kelas_buah{n} = 'jeruk'; end % mengujikan data uji sesuai dengan garis batas yang terbentuk label = predict(obj,[ciri_h,ciri_s]); % menampilkan sebaran data latih dan data uji hold on h3 = gscatter(ciri_h,ciri_s,label,'gm','v^',[],'off'); set(h3,'LineWidth',2) xlabel('hue') ylabel('saturation') legend('apel (latih)','jeruk (latih)','daerah apel (latih)',... 'daerah jeruk (latih)','garis batas','apel (uji)','jeruk (uji)',... 'Location','SE') title('{\bf Klasifikasi buah apel dan jeruk (pengujian)}') % menghitung nilai akurasi pengujian jumlah_benar = 0; for n = 1:jumlah_file if isequal(label{n},kelas_buah{n}) jumlah_benar = jumlah_benar+1; end end akurasi = jumlah_benar/jumlah_file*100; disp(['akurasi = ',num2str(akurasi),' %'])
Grafik sebaran data uji pada masing-masing kelas ditunjukkan pada gambar berikut:

Akurasi yang dihasilkan pada proses pengujian adalah sebesar

Besarnya nilai akurasi yang dihasilkan menunjukkan bahwa metode linear discriminant analysis sangat baik diterapkan pada klasifikasi jenis buah.
3. Pembuatan GUI MATLAB
Source code yang digunakan untuk dalam pembuatan GUI MATLAB adalah
function varargout = main_program(varargin) % MAIN_PROGRAM MATLAB code for main_program.fig % MAIN_PROGRAM, by itself, creates a new MAIN_PROGRAM or raises the existing % singleton*. % % H = MAIN_PROGRAM returns the handle to a new MAIN_PROGRAM or the handle to % the existing singleton*. % % MAIN_PROGRAM('CALLBACK',hObject,eventData,handles,...) calls the local % function named CALLBACK in MAIN_PROGRAM.M with the given input arguments. % % MAIN_PROGRAM('Property','Value',...) creates a new MAIN_PROGRAM or raises the % existing singleton*. Starting from the left, property value pairs are % applied to the GUI before main_program_OpeningFcn gets called. An % unrecognized property name or invalid value makes property application % stop. All inputs are passed to main_program_OpeningFcn via varargin. % % *See GUI Options on GUIDE's Tools menu. Choose "GUI allows only one % instance to run (singleton)". % % See also: GUIDE, GUIDATA, GUIHANDLES % Edit the above text to modify the response to help main_program % Last Modified by GUIDE v2.5 03-Apr-2019 12:48:18 % Begin initialization code - DO NOT EDIT gui_Singleton = 1; gui_State = struct('gui_Name', mfilename, ... 'gui_Singleton', gui_Singleton, ... 'gui_OpeningFcn', @main_program_OpeningFcn, ... 'gui_OutputFcn', @main_program_OutputFcn, ... 'gui_LayoutFcn', [] , ... 'gui_Callback', []); if nargin && ischar(varargin{1}) gui_State.gui_Callback = str2func(varargin{1}); end if nargout [varargout{1:nargout}] = gui_mainfcn(gui_State, varargin{:}); else gui_mainfcn(gui_State, varargin{:}); end % End initialization code - DO NOT EDIT % --- Executes just before main_program is made visible. function main_program_OpeningFcn(hObject, eventdata, handles, varargin) % This function has no output args, see OutputFcn. % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % varargin command line arguments to main_program (see VARARGIN) % Choose default command line output for main_program handles.output = hObject; % Update handles structure guidata(hObject, handles); movegui(hObject, 'center'); % UIWAIT makes main_program wait for user response (see UIRESUME) % uiwait(handles.figure1); % --- Outputs from this function are returned to the command line. function varargout = main_program_OutputFcn(hObject, eventdata, handles) % varargout cell array for returning output args (see VARARGOUT); % hObject handle to figure % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Get default command line output from handles structure varargout{1} = handles.output; % --- Executes on button press in pushbutton1. function pushbutton1_Callback(hObject, eventdata, handles) % hObject handle to pushbutton1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % menampilkan menu browse file [filename,pathname] = uigetfile({'*.jpg'}); % jika ada file yg dipilih maka mengeksekusi perintah2 yg ada di bawahnya if ~isequal(filename,0) % mereset button2 axes(handles.axes1) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes2) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes3) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes4) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) set(handles.uitable1,'Data',[],'ForegroundColor',[0 0 0]) set(handles.edit1,'String','') set(handles.edit2,'String','') set(handles.pushbutton2,'Enable','on') set(handles.pushbutton3,'Enable','off') set(handles.pushbutton4,'Enable','off') set(handles.pushbutton5,'Enable','off') % membaca file citra Img = imread(fullfile(pathname,filename)); % menampilkan citra pada axes axes(handles.axes1) imshow(Img) title('Citra RGB') % menampilkan nama file citra pada edit text set(handles.edit1,'String',filename) % menyimpan variabel Img pada lokasi handles agar dapat dipanggil oleh % pushbutton yg lain handles.Img = Img; guidata(hObject, handles) else return end % --- Executes on button press in pushbutton2. function pushbutton2_Callback(hObject, eventdata, handles) % hObject handle to pushbutton2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % mereset button2 axes(handles.axes2) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes3) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes4) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) set(handles.uitable1,'Data',[],'ForegroundColor',[0 0 0]) set(handles.edit2,'String','') set(handles.pushbutton3,'Enable','on') set(handles.pushbutton4,'Enable','off') set(handles.pushbutton5,'Enable','off') % memanggil variabel Img yang ada di lokasi handles Img = handles.Img; % mengkonversi ruang warna citra rgb menjadi L*a*b cform = makecform('srgb2lab'); lab = applycform(Img,cform); % menampilkan citra pada axes axes(handles.axes2) imshow(lab) title('Citra L*a*b') % menyimpan variabel lab pada lokasi handles agar dapat dipanggil oleh % pushbutton yg lain handles.lab = lab; guidata(hObject, handles) % --- Executes on button press in pushbutton3. function pushbutton3_Callback(hObject, eventdata, handles) % hObject handle to pushbutton3 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % mereset button2 axes(handles.axes3) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes4) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) set(handles.uitable1,'Data',[],'ForegroundColor',[0 0 0]) set(handles.edit2,'String','') set(handles.pushbutton4,'Enable','on') set(handles.pushbutton5,'Enable','off') % memanggil variabel lab yang ada di lokasi handles lab = handles.lab; % mengekstrak komponen b dari citra L*a*b b = lab(:,:,2); % melakukan thresholding terhadap komponen b bw = b>140; % melakukan operasi morfologi untuk menyempurnakan hasil segmentasi bw = imfill(bw,'holes'); % menampilkan citra pada axes axes(handles.axes3) imshow(bw) title('Citra Biner') % menyimpan variabel bw pada lokasi handles agar dapat dipanggil oleh % pushbutton yg lain handles.bw = bw; guidata(hObject, handles) % --- Executes on button press in pushbutton4. function pushbutton4_Callback(hObject, eventdata, handles) % hObject handle to pushbutton4 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % mereset button2 axes(handles.axes4) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) set(handles.uitable1,'Data',[],'ForegroundColor',[0 0 0]) set(handles.edit2,'String','') set(handles.pushbutton5,'Enable','on') % memanggil variabel Img dan bw yang ada di lokasi handles Img = handles.Img; bw = handles.bw; % mengkonversi ruang warna citra rgb menjadi hsv hsv = rgb2hsv(Img); % mengekstrak komponen h, s, dan v h = hsv(:,:,1); s = hsv(:,:,2); v = hsv(:,:,3); % mengubah nilai background menjadi nol h(~bw) = 0; s(~bw) = 0; v(~bw) = 0; hsv = cat(3,h,s,v); % menampilkan citra pada axes axes(handles.axes4) imshow(hsv) title('Citra HSV') % menghitung rata-rata nilai hue dan saturation nilai_h = mean(h); nilai_s = mean(s); ciri = [nilai_h,nilai_s]; % menampilkan rata-rata nilai hue dan saturation pada tabel data = cell(2,2); data{1,1} = 'Hue'; data{2,1} = 'Saturation'; data{1,2} = nilai_h; data{2,2} = nilai_s; set(handles.uitable1,'Data',data,'RowName',1:2) % menyimpan variabel ciri pada lokasi handles agar dapat dipanggil oleh % pushbutton yg lain handles.ciri = ciri; guidata(hObject, handles) % --- Executes on button press in pushbutton5. function pushbutton5_Callback(hObject, eventdata, handles) % hObject handle to pushbutton5 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % mereset button2 set(handles.edit2,'String','') % memanggil variabel ciri yang ada di lokasi handles ciri = handles.ciri; % load variabel obj load obj % mengujikan data uji sesuai dengan garis batas yang terbentuk label = predict(obj,ciri); % menampilkan hasil klasifikasi pada edit text set(handles.edit2,'String',label) function edit1_Callback(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit1 as text % str2double(get(hObject,'String')) returns contents of edit1 as a double % --- Executes during object creation, after setting all properties. function edit1_CreateFcn(hObject, eventdata, handles) % hObject handle to edit1 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end function edit2_Callback(hObject, eventdata, handles) % hObject handle to edit2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % Hints: get(hObject,'String') returns contents of edit2 as text % str2double(get(hObject,'String')) returns contents of edit2 as a double % --- Executes during object creation, after setting all properties. function edit2_CreateFcn(hObject, eventdata, handles) % hObject handle to edit2 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles empty - handles not created until after all CreateFcns called % Hint: edit controls usually have a white background on Windows. % See ISPC and COMPUTER. if ispc && isequal(get(hObject,'BackgroundColor'), get(0,'defaultUicontrolBackgroundColor')) set(hObject,'BackgroundColor','white'); end % --- Executes on button press in pushbutton6. function pushbutton6_Callback(hObject, eventdata, handles) % hObject handle to pushbutton6 (see GCBO) % eventdata reserved - to be defined in a future version of MATLAB % handles structure with handles and user data (see GUIDATA) % mereset button2 axes(handles.axes1) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes2) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes3) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) axes(handles.axes4) cla reset set(gca,'XTick',[]) set(gca,'YTick',[]) set(handles.uitable1,'Data',[],'ForegroundColor',[0 0 0]) set(handles.edit1,'String','') set(handles.edit2,'String','') set(handles.pushbutton2,'Enable','off') set(handles.pushbutton3,'Enable','off') set(handles.pushbutton4,'Enable','off') set(handles.pushbutton5,'Enable','off')
Tampilan GUI Matlab yang dihasilkan oleh algoritma dan pemrograman di atas adalah sebagai berikut:
Klasifikasi jenis buah apel


Klasifikasi jenis buah jeruk


File source code lengkap beserta citra pada pemrograman di atas dapat diperoleh melalui halaman berikut ini: Source code
Penerapan algoritma Linear Discriminant Analysis (LDA) untuk klasifikasi citra buah apel dan jeruk dapat dilihat pada video tutorial berikut ini:

Posted on April 3, 2019, in Data mining, Pengenalan Pola, Pengolahan Citra and tagged algoritma linear discriminant analysis, contoh aplikasi pengolahan citra, contoh penerapan linear discriminant analysis, contoh penerapan metode lda, definisi linear discriminant analysis, definisi pengolahan citra, klasifikasi citra menggunakan linear discriminant analysis, lda adalah, linear discriminant analysis adalah, metode linear discriminant analysis, pengolahan citra adalah, source code matlab lda, source code matlab linear discriminant analysis. Bookmark the permalink. 12 Comments.
mas untuk tahap pelatihan bisa nampilin dalam bentuk tabel ga?
Untuk tahap pelatihan bisa ditampilkan dalam bentuk tabel
mas untuk thresholding dan hsv warna hijau hanya menampilkan gelap ya?
Nilai threshold nya bisa diatur supaya warna hijau dapat terdeteksi
Mas yang di file proses pengujian itu kok legend yang (latih ) tidak keluar ya cara menghubungkannya bagimana ya mas ?
Source code di atas tidak bisa dijalankan jika hanya dicopy paste saja
maaf mas mau tanya, cara untuk membaca hasil (grafik) dari data latih dan data uji nya bagaimana ya mas?
terima kasih.
Bisa dipelajari lebih lanjut
maaf mas ingin bertanya, untuk source code data uji sama data latihnya di letakkan dalam satu folder atau bagaimana ya? saat dipisah proses klasifikasi di gui tidak muncul terimakasih
Source code lengkap bisa dibeli melalui tokopedia sehingga bisa dipelajari lebih lanjut
Kak kenapa pas bagian klasifikasi penggunaan variabel obj nya itu eror ?
Source code lengkap bisa dibeli di tokopedia sehingga bisa langsung dirun tanpa error dan bisa dikembangkan