Sunday, March 20, 2016

Real time image and video processing with MATLAB ภาค 2

กลับมาอีกครั้ง สำหรับการเรียนรู้วิธีการทำประมวลวีดิโอเบื้องต้น จากที่ไปได้เวบที่ดีและเขียนไว้นานแล้ว (อ่านบทความเก่า >>> RealtimeVDO Processing) ในเวบเจ้าของที่ข้าพเจ้าไปอ่าน และหยิบ source code มาใช้นั้นจะอาศัย timer function และการกำหนด trigger เพื่อเข้าไปประมวลผลภาพหรือเรียกว่า frame จากนั้นนำผลลัพธ์มาแสดงเป็นกราฟ (เวบต้นฉบับ แสดงค่าเฉลี่ยของภาพ) ในบทความนี้ข้าพเจ้าได้นำ source code เดิมมาปรับให้ใช้งานเป็น GUI และนำข้อมูลที่ใช้เขียนกราฟมาแสดงที่ตาราง และเพิ่มความสามารถให้บันทึกเป็น MS excel ด้วย หน้าตาโปรแกรมประมาณนี้



ตัวโปรแกรมทั้งหมดจะเก็บไว้ที่นี่ ลองเอาไปลองใช้กันด้เลยนะ >>> UPCam_Monitoring
แต่ก็บอกไว้ก่อนนะครับว่าโปรแรกมยังไม่สมบูรณ์ไม่มีการ optimization มีข้อผิดพลาดอยู่หลายจุดที่จะต้องพัฒนาต่อเบื้องต้นทำงานได้ และน่าจะเป็นจุดเริ่มต้นสำหรับคนอื่นๆ เผื่อเอาไปใช้กับงานของตัวเอง
จากนี้ไปจะนำโปรแกรมดังกล่าวไปใช้งานด้านต่างๆ ซึ่งจะนำมาอัพเดทเรื่อยๆ เผื่อตรงกับความต้องการของใครก็นำไปใช้ได้เลย หากต้องการนำไปพัฒนาต่อข้าพเจ้าก็ยินดียิ่ง

ขอยกตัวอย่างคำสั่งที่เขียนไว้ใน callback function ของปุ่มกด ConnectCAM ดังนี้

% --- Executes on button press in pushConnectCam.
function pushConnectCam_Callback(hObject, eventdata, handles)
% hObject    handle to pushConnectCam (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)guidata(hObject,handles);
NumberFrameDisplayPerSecond = str2double(get(handles.edit1,'String'));
%handles.FPS=1/NumberFrameDisplayPerSecond;
check1=get(handles.radioCam1,'value');
check2=get(handles.radioCam2,'value');
check3=get(handles.radioCam3,'value');

hFigure=figure(2);
if (check1==1)
handles.vid = videoinput('winvideo',1);
elseif (check2==1)
handles.vid = videoinput('winvideo',2);
elseif (check3==1)
handles.vid = videoinput('winvideo',3);
end

% Set parameters for video
% Acquire only one frame each time
set(handles.vid,'FramesPerTrigger',1);
% Go on forever until stopped
set(handles.vid,'TriggerRepeat',Inf);
% Get a grayscale image
set(handles.vid,'ReturnedColorSpace','grayscale');
triggerconfig(handles.vid, 'Manual');
% set up timer object
handles.TimerData=timer('TimerFcn', {@FrameRateDisplay,handles.vid,handles.figure1},'Period',1/NumberFrameDisplayPerSecond,'TasksToExecute',inf,'ExecutionMode','fixedRate','BusyMode','drop');
% Start video and timer object  FrameRateDisplay
set(handles.uitable1,'Data',[])
start(handles.vid);
start(handles.TimerData);
%data=handles.data;
%plot(data);

uiwait(hFigure);
%xlswrite('DatA_sample.xls',handles.DataValues);
% Clean up everything
%stop(handles.TimerData);
%delete(handles.TimerData);
stop(handles.vid);
delete(handles.vid);
guidata(hObject,handles);


ส่วนนี้เป็น function ที่เขียนแยกไว้ ก็ได้เพิ่มเติมจาก source code ของต้นฉบับนิดเดียว

function [Values] = FrameRateDisplay(hOject, event,vid,guiHandle)
persistent IM;
persistent handlesRaw;
persistent handlesPlot;
persistent handlesData;

trigger(vid);
IM=getdata(vid,1,'uint8');

if isempty(handlesRaw)
  
   % if first execution, we create the figure objects     
   subplot(2,1,1);
   handlesRaw=imagesc(IM);colorbar;
   title('Live');
   % Plot first value
   Values=mean(IM(:));
   subplot(2,1,2);
   handlesPlot=plot(Values);
   title('Average of Frame');
   xlabel('Frame number');
   ylabel('Average value (au)');

elseif ~isempty(guiHandle)

    handles = guihandles(guiHandle);
    currentTime = datestr(now,'HH:MM:SS');
   
    % update the table

   % We only update what is needed
   set(handlesRaw,'CData',IM);
   Value=mean(IM(:));
   OldValues=get(handlesPlot,'YData');
   set(handlesPlot,'YData',[OldValues Value]);
  
   handlesData = get(handles.uitable1,'Data');
   handlesData = [handlesData ; {currentTime , Value}];
   set(handles.uitable1,'Data',handlesData);
  
end

เมื่อปิด figure(2) ซึ่งก็คือภาพที่แสดงรูป monochrome (imagesc) กับกราฟค่า mean แบบเวลาจริง โปรแกรมก็จะหยุดทำงานเพราะเขียน uiwait() รอว่า figure(2) ถูกปิดเมื่อไรให้ปิดการเชื่อมต่อและ timer นอกจากนี้สามารถบันทึกค่า เวลาและค่าเฉลี่ย เป็นไฟล์ MS Excel ได้ ซึ่งในที่นี้ข้าพเจ้าได้เขียน ค่าช่วงเวลา $\Delta{t}$ จาก frame-to-frame ลงใน excel ด้วย ภาพด้านล่างแสดงการเขียนกราฟจากค่าที่บันทึกใน excel เทียบกับกราฟที่ plot แบบ realtime



สังเกตใน worksheet จะมีช่อง time (sec) เพิ่มขึ้นมาซึ่งเขียนมาจากการนำ frame per sec (FPS) มาคำนวณ โดยที่ $\Delta t $ = $\frac{1}{FPS}$ ดังนั้นแกนเวลาของแต่ละเฟรมจะเป็น $n\times \Delta t $ เมื่อ n=1, 2, 3, . . . คือ ตัวเลขบอกลำดับที่ของ frame
หากต้องการให้โปรแกรมทำงานใหม่อีกครั้ง ให้กดปุ่ม "Clear All" ก่อน เพื่อเคลียร์ memory และค่าที่ค้างก่อนหน้าทิ้ง

แนวการพัฒนาโปรแกรต่อจากนี้ ได้แก่

-Pre-Processing เพื่อเลือกสีก่อนก่อนจะใช้วิเคราะห์จริง เนื่องจากตัวอย่างแต่ละชนิด ให้สัญญาณที่เหมาะสมไม่เหมือนกัน
- การแยกพิจารณาสี ที่เป็น monochrome แยกวิเคราะห์ R-channel G-channel B-channel เพื่อดูว่าสิ่งที่กำลังวิเคราะห์องค์ประกอบสีไหนที่เป็นสีหลักของการวิเคราะห์

-