Tuesday, April 28, 2020

Re-post กลับมาเขียนอีกครั้ง

ผมกลับมาใช้งาน MATLAB อีกครั้งรอบนี้ใช้เวอร์ชัน 2018a แต่เริ่มแบบเดิม ทดสอบการทำ GUI สำหรับเปิดภาพ แสดงเป็น RGB-, Red-, Green-, Blue- Grayscale เลือกแสดงที่ละแบบโดยใช้ฟังก์ชัน Off





ครั้งนี้ลองใช้ pushbutton แทน radio butoon การเขียนโปรแกรมควบคุมไม่ต่างกัน ใช้งานเช่นเดิม ลองดูตัวอย่างการใช้งานโปรแกรมนี้ดังภาพด้านล่าง









ตัวอย่าง source code ตรงไปตรงมา (ไม่ต้องหาความเป็นมืออาชีพด้านการเขียนโปรแกรมในบล็อก ผมนะครับ 555)

%สำหรับเปิดไฟล์รูปในโฟลเดอร์
function pushOpen_Callback(hObject, eventdata, handles)
% hObject    handle to pushOpen (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
[F,PathName,FilterIndex] = uigetfile({'*.*','All Files(*.*)'}, 'Select your File ');
input=strcat(PathName,F);
handles.RGBimage=importdata(input);
%====Display image on axesImage ======%
axes(handles.axesImage);
imshow(handles.RGBimage);%axis equal;axis tight;
hpixinfo = impixelinfo;
%zoom on;
%axis off;
%figure()
%imshow(handles.RGBimage);
guidata(hObject,handles);

% ส่วนควบคุม push button ที่ชื่อ tag ว่า pushRed
 function pushRed_Callback(hObject, eventdata, handles)
% hObject    handle to pushRed (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

axes(handles.axesImage);
handles.RGBimage(:,:,2) = 0;
handles.RGBimage(:,:,3) = 0;
imshow(handles.RGBimage); title('Red-component image');axis equal;axis tight;axis off;impixelinfo;

off=[handles.pushRGB handles.pushGreen handles.pushGray handles.pushBlue];
Turn_Off(off);



ภาพที่นำมาทดสอบ นำมาจาก https://scholarlykitchen.sspnet.org/2019/11/06/born-digital-the-expanding-universe-of-research-content/  ไฟล์ต่างๆ ดาวโหลดได้จากที่นี่ >>> Download files

Wednesday, January 1, 2020

On the beginning (MATLAB GUIDE)

   การเรียนรู้ MATLAB ของผมเกิดขึ้นจากความจำเป็นทั้งสิ้น ที่ต้องหาเครื่องมือมาใช้ในการคำนวณในส่วนงาน ด้วยไม่เคยเรียนเกี่ยวกับ programming มาก่อนเลย เรียนแต่คอมพิวเตอร์พื้นฐานที่ทางสถาบันการศึกษาทุกแห่งต้องจัดให้เป็นวิชาพื้นฐานให้ นักเรียน นักศึกษา ต้องลงทะเบียนเรียนกันทุกคนนั่นแหละครับ
   ด้วยพื้นฐานที่ไม่ถูกฝึกมาทาง programming  ซึ่งเป็นเหตุผลหนึ่งที่เลือกใช้ MATLAB ดังนั้น source code ที่ผมเขียนขึ้นจะตรงไปตรงมา ผมต้องการอะไรผมก็จะเขียนอย่างนั้นเลย อาจจะไม่ฉลาดเหมือน programmer เขาเขียนกันนะครับ อันนี้ขอทำความเข้าใจไว้เบื้องต้นก่อนครับ ตอนเริ่มแรกผมศึกษาจากรุ่นพี่ที่เรียนด้วยกันและทำงานวิจัยด้วยกันครับ หลังจบก็แยกย้ายกันทำงานติดต่อกันบ้าง มีปัญหาก็สอบถาม หาข้อมูลตาม cyber space ถามผู้รู้บ้าง (ในกรณีที่พยายามด้วยตัวเองแล้ว) สุดท้ายความรู้มันก็ผสมปนเปกันออกมาพอจะใช้งานได้ครับ พอมีเครื่องมือทุ่นแรงกาย พลังสมอง ลงไปบ้าง ไม่ต้องไปนั่งคำนวณในกระดาษ เขียนด้วยปากกาซะทั้งหมด

   เอาเป็นว่า blog นี้ ผมจะเขียนบันทึกงานที่ผมทำในแต่ละครั้งนะครับ เพื่อประโยชน์ดังต่อไปนี้ครับ

- สำหรับตัวเอง กันลืม หรือจะได้กลับมารื้อค้นนำไปใช้ในภายหน้าครับ

- สำหรับคนอื่น เผื่อใครติดปัญหา แล้วสิ่งที่ผมเคยทำมันเป็นทางออกสำหรับเขา ผมก็ยินดีด้วยครับ

  ถึงแม้ตัวข้าพเจ้าเองจะเป็นนักวิทยาศาสตร์ชั้นปลายแถว แต่ก็จะพยายามทำงานที่มีประโยชน์ทั้งต่อตัวเองและคนอื่น  เก็บประสบการณ์ไปเรื่อยๆ หากท่านใดเห็น blog นี้แล้ว อยากแนะนำเพิ่มเติม เต็มที่ครับผมน้อมรับคำแนะนำ คำสั่งสอนครับและทางตรงกันข้าม หากใครมีปัญหาติดขัดตรงไหนก็ฝากข้อความไว้ได้เลยครับ หากผมตอบได้ผมจะรีบจัดการให้ทันที แต่ถ้าผมตอบไม่ได้ก็จะพยายามหาคำตอบ จากแหล่งอื่นให้ครับ ดังนั้นผมจะขอเริ่มแล้วครับ

Thursday, April 21, 2016

Webcam base analysis ภาคต่อ

ครั้งนี้กลับมาเขียนเรื่องราวเกี่ยวกับการติดต่อกล้องเวบแคมผ่าน MATLAB อีกครั้งหนึ่ง อันที่จริงชอต์ฟแวร์ถูกพัฒนาขึ้นมานานแล้ว ส่วนโค๊ดต้นฉบับบางส่วนที่พัฒนาเพิ่มเข้ามานั้นมีที่มาจากเวบไซต์หนึ่งและจะนำมากำกับไว้ในโอกาศต่อไปรูปร่างหน้าตาของโปรแกรมประมาณนี้


หลังจากติดต่อกล้องเรียบร้อยแล้ว ข้าพเจ้าก็กด snapshot โปรแกรมจะนำภาพที่ได้ไปคำนวณตามที่เขียนไว้ และจะผลดังรูป ซึ่งส่วนนี้เองที่ได้เพิ่มเข้ามาใหม่ เพื่อแยกวัตถุออกจากพื้นหลัง
ไฟล์ที่จำเป็นสามารถดาวโหลดได้จาก link

จากตัวอย่างด้านบนหลายคนอาจจะสงสัยว่ามันจะมีประโยชน์อะไร ผมเลยทดสอบเล่นๆ ถ้าเป็นภาพเนื้อที่มีไขมันแทรก แล้วอยากจะทราบว่ามีไขมันแทรกมากน้อยเพียงไร สามารถเกรดเนื้อให้อยู่ในระดับไหน โคเนื้อยิ่งมีไขมันแทรกมาก เนื้อจะมีราคาสูง (ข้อมูลเบื้องต้น วากิว) ผลลัพธ์ที่ได้ก็เป็นประมาณนี้เลยครับ

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


หัวข้อนี้ไม่ได้ลง source code ไว้เพราะมีหลายส่วนก็ขอให้เข้าไปศึกษาและปรับใช้กันเอง

สำหรับ code ต้นฉบับมาจากที่นี่ครับ ลองเข้าไปดูได้เลย >>>  original source code


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 เพื่อดูว่าสิ่งที่กำลังวิเคราะห์องค์ประกอบสีไหนที่เป็นสีหลักของการวิเคราะห์

-

Sunday, October 19, 2014

Arduino interface with MATLAB: GUI Real Time Plot

เป็นโอกาศดีครับมีคนเข้ามาสอบถามว่าถ้าต้องการติดต่อกับบอร์ด Arduino ด้วย MATLAB และต้องการสร้าง GUI ด้วยจะทำอย่างไร ผมก็ยังไม่เคยทำแต่ก็ลองหาดูว่ามีใครทำอะไร อย่างไรบ้าง ก็พบว่าน่าสนใจดีเลยทีเลยครับ เพราะ MATLAB มีคนเขียน I/O มาให้เราใช้อยู่แล้ว ลองเข้าไปอ่านและเอามาใช้ดูได้ครับ ตามนี้

http://www.mathworks.com/hardware-support/arduino-matlab.html

หรือที่นี่

http://www.mathworks.com/matlabcentral/fileexchange/32374-matlab-support-for-arduino--aka-arduinoio-package

(ผมใช้ที่นี่ ในไซต์นี้ยังมี example ให้ศึกษาทดลอง ก่อนที่จะไปทำของเล่นของตัวเองนะครับ ถือว่าดีมาก)

สิ่งที่จะต้องมีหากต้องการเล่นของเล่นใหม่นี้

1. Arduino board ซึ่งหาซื้อได้ในหลายช่องทางราคาถูก (ประมาณ 300 บาทก็หามาเล่นได้แล้วครับ)
2. Sketch เอาไว้เขียนโปรแกรมสำหรับฝั่งบอร์ด Arduino ซึ่งดาวว์โหลดได้โดยตรงจากเวบด้านบนครับ
3. แน่นอน MATLAB และไฟล์สำหรับติดต่อกับ Arduino ซึ่งก็ดาวว์โหลดจาก Mathwork (ตามลิ้งค์ด้านบน)
4. บอร์ดทดลองและชิ้นส่วนอิเล็กทรอนิกนส์ตามต้องการ (อาจเริ่มจากการวัดค่าโวลต์ จากตัวต้านทานปรับค่าได้ก่อนเพื่อทำความเข้าการติดต่อระหว่าง บอร์ดกับ MATLAB)
5. แนวคิด ความต้องการที่จะทำของเล่นสักอย่างหนึ่ง โดยรับค่ามาจาก Arduino แต่สั่งงานผ่าน MATLAB

ก่อนที่จะทำการทดลองต้องโปรแกรม I/O ลงไปในบอร์ด Arduino ก่อนผ่าน Sketch ไฟล์ที่กล่าวถึงหาจากลิ้งค์ด้านบนซึ่งจะอยู่ใน โฟลเดอร์ pde ให้มองหาไฟล์ดังต่อไปนี้ครับ adio.pde, adioe.pde, adioes.pde (ผมเลือกใช้ไฟล์แรก ส่วนนี้ขอให้ไปดูรายละเอียดเอง) ในไฟล์ zip มีไฟล์ที่จำเป็นต้องใช้ ซึ่งเราต้องคัดลอกไฟล์นี้ไปไว้ในโฟลเดอร์เดียวกับโปรแกรมที่เราพัฒนาขึ้นมาด้วย (ไฟล์ดังกล่าวชื่อ arduino.m)

ผมทดลองและทดสอบ การอ่านค่าจาก IR sensor ผ่าน analogRead ฟังก์ชัน (ขา A2) ผลการทดสอบเป็นดังรูป ส่วนรายละเอียดเดี๋ยวจะมาเขียนต่อครับ (ในรูป แกน x ยังไม่ใช่เวลาจริงนะครับยังไม่ศึกษาส่วนนี้ ส่วนแกน y ยังไม่ได้แปลงค่า ยังคงเป็น ค่าตาม ADC 10-bit ของ Arduino อยู่)


ส่วนรูปนี้คือ วงจร IR sensor ง่ายๆ ที่ใช้ทดสอบครับ


มีคำอธิบายการศึกษาพื้นฐาน เกี่ยวกับการติดต่อ Arduino ผ่าน MATLAB ดังนี้
คำสั่งติดต่อ MATLAB
a=arduino('COMPORT'); % ในกรณีเครื่องผมเป็น COM11

ในที่นี้  COMPORT คือ พอร์ตที่ Arduino ต่อกับคอมพิวเตอร์เราอยู่ การประกาศ input/output ตรงนี้สามารถทำได้ในหลายรูปแบบ ดูจากเอกสารอ้างอิงได้เลย

a.pinMode(2,'input'); % a ในที่นี้ก็คือตัวแปรที่ใช้แทน Arduino
a.pinMode(3,'input');
a.pinMode(4,'input');
a.pinMode(5,'input');

ประกาศให้ อะนาลอก A2-A5 เป็น input พอร์ต (ประกาศเผื่อไว้ จริงๆ ในงานนี้ใช้แค่ A2)
จากนั้นก็เขียนรับข้อมูลจาก ขาอะนาลอก A2 ด้วยคำสั่งนี้

b=a.analogRead(2);

b คือ ตัวแปรที่รับค่าจากขา A2 แต่คำสั่งนี้จะรับค่ามาครั้งเดียว ถ้าหากต้องการ ให้ MATLAB วนรับค่าตลอดเวลา (ให้ทำงานแบบวนไม่มีที่สิ้นสุด เหมือน void loop ใน sketch) ในที่นี้ผมใช้ while loop ที่มีเงื่อนไขเป็นจริงเสมอ ดังนี้

x=0;
while(1)
b=a.analogRead(2);
x=[x,b];
end

ในกรณีนี้ MATLAB จะรับค่าจาก A2 มาตลอดเวลา และเก็บค่าไว้ในตัวแปร x ส่วน source code เต็มและ file.fig หาได้จากที่นี่เลยครับ >>> Download (ไฟล์มีเวลาจำกัดอาจถูกลบไปก่อน)

ส่วนนี่คือ source code ที่เขียนบังคับ GUI ครับ
%=========================================
function varargout = IR_GUIArduino(varargin)
% IR_GUIARDUINO MATLAB code for IR_GUIArduino.fig

% Begin initialization code - DO NOT EDIT
gui_Singleton = 1;
gui_State = struct('gui_Name',       mfilename, ...
                   'gui_Singleton',  gui_Singleton, ...
                   'gui_OpeningFcn', @IR_GUIArduino_OpeningFcn, ...
                   'gui_OutputFcn',  @IR_GUIArduino_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 IR_GUIArduino is made visible.
function IR_GUIArduino_OpeningFcn(hObject, eventdata, handles, varargin)
% Choose default command line output for IR_GUIArduino
handles.output = hObject;
% Update handles structure
guidata(hObject, handles);

% --- Outputs from this function are returned to the command line.
function varargout = IR_GUIArduino_OutputFcn(hObject, eventdata, handles)
% Get default command line output from handles structure
varargout{1} = handles.output;


% --- Executes on button press in pushconnect.
function pushconnect_Callback(hObject, eventdata, handles)

global a;
a=arduino('COM11')
a.pinMode(2,'input');
a.pinMode(3,'input');
a.pinMode(4,'input');
a.pinMode(5,'input');

% --- Executes on button press in pushdisconnect.
function pushdisconnect_Callback(hObject, eventdata, handles)
delete(instrfind({'Port'},{'COM11'}))

% --- Executes on button press in pushmeasure.
function pushmeasure_Callback(hObject, eventdata, handles)

global a;

x=0;

while(1)
b=a.analogRead(2);
x=[x,b];

axes(handles.axes1);
plot(x,'g');
grid
drawnow
set(handles.axes1,'YGrid','on',...
    'YColor',[0.247058823529412 0.247058823529412 0.247058823529412],...
    'XGrid','on',...
    'XColor',[0.247058823529412 0.247058823529412 0.247058823529412],...
    'Color',[0 0 0]);
xlabel('time(s)');
ylabel('Intensity (a.u.)');
hold(handles.axes1,'all');
end

% --- Executes on button press in pushclear.
function pushclear_Callback(hObject, eventdata, handles)
cla(handles.axes1,'reset')

% --- Executes on button press in pushExit.
function pushExit_Callback(hObject, eventdata, handles)
button = questdlg('Do you want to quit?', ...
        'Exit Dialog','Yes','No','No');
switch button
            case 'Yes',
              %Save variables to matlab.mat
              save
              close(ancestor(hObject,'figure'))
             
            case 'No',
              quit cancel;
end
%=========================================
ส่วนไฟล์ ที่เป็น .fig สร้างเองเองละกันครับ

 (แต่อย่าลืมเปลี่ยน COMPORT ให้ตรงกันนะครับ)

สิ่งที่ต้องศึกษาหาความรู้ต่อไปคือ เวลา การจัดเก็บข้อมูล การใช้งานในโหมดอื่นๆ

*******************************************
 ปัจจุบันข้าพเจ้าไม่พัฒนา Arduino MATLAB แล้วเพราะมันดูไม่เข้ากัน (ในความคิดข้าพเจ้า)
เพราะ MATLAB มีค่าลิขสิทธิ์ ข้าพเจ้าจึงหันไปมองหา open source ที่จะมาพัฒนาร่วมกับ
Arduino น่าจะดีกว่า
*******************************************

เอกสารอ้างอิง

Arduino IO package: Slides and Examples  >>> read more

Friday, May 3, 2013

Create slider with GUI MATLAB part II

เพิ่มเติมจากของเดิมนิดหน่อย โดยเอา slider ไปปรับค่ารัศมีของวงกลม หลักการเหมือนเดิมครับ ค่าที่รับมาจาก slider หรือ edit text ถูกนำไปให้ตัวแปรที่ใช้กำหนดรัศมีของวงกลม ตามรายละเอียดด้านล่างครับ

r คือตัวแปรสำหรับรับค่าจาก slider หรือ edit text

% รับค่าจาก slider และสั่งวาดกราฟวงกลม ไปบน axes1
handles.axes1;
r=str2double(handles.sliderValue);
t=0:pi/24:2*pi;
x=r*cos(t);
y=r*sin(t);
plot(x,y,x,y,'r.')
% รับค่าจาก edit text และสั่งวาดกราฟวงกลม ไปบน axes1
handles.axes1;
editValue=str2double(get(handles.edit1,'String'));
r=editValue;
t=0:pi/24:2*pi;
x=r*cos(t);
y=r*sin(t);
plot(x,y,x,y,'r.')

หน้าตา GUI ก็ประมาณนี้ครับ  ดาวโหลดไฟล์ที่นี่เลยครับ ==>>> download files


ในรายละเอียดยังมีส่วนที่ต้องแก้ไขเพื่อให้ GUI ออกมาใช้งานได้อย่างดีเยี่ยม ซึ่งคิดว่าหากใครต้องการศึกษา มันก็จะเป็นแบบฝึกหัดอย่างดีเลยครับ เช่น เพิ่ม axis square และ
axis([-100 100 -100 100]) เข้าไปในคำสั่ง plot เป็นต้น
 

Thursday, May 2, 2013

Create slider with GUI MATLAB part I

 ครั้งนี้ว่าด้วยเรื่องการใช้งาน slider ครับ เริ่มต้นจากการใช้งานที่ง่ายที่สุดก่อน สำหรับแนวคิดในเรื่องนี้ คือ การใช้งาน slider โดยแจ้งสถานะหรือตำแหน่งสเกลให้ไปปรากฎบน edit text และในทางตรงกันข้ามหากป้อนตัวเลข (ไม่เกิน min, max เพราะยังไม่ได้เขียนเงื่อนไขกันไว้) ก็เป็นการกำหนดให้ slider อยู่ ณ ตำแหน่งนั้นได้เช่นกัน ประโยนช์สำหรับ slider นั้นมีเยอะครับ โดยรวมหรือที่เข้าใจกันได้ง่ายๆก็คือ เอาไว้ใช้ปรับค่าพารามิเตอร์ต่างๆ ตามต้องการ โดยการเลื่อนปุ่ม slider นี่แหละครับ

นี่เป็นหน้าตา GUI ที่ทำขึ้นแบบง่ายๆ และไฟล์ต่างๆ โหลดจากที่นี่ครับ ==>>> Slider01


 รายละเอียดที่สำคัญใน GUI-Slider

% --- Executes on slider movement.
function slider1_Callback(hObject, eventdata, handles)

set(handles.slider1,'Min',0)
set(handles.slider1,'Max',100)
slider_value = get(handles.slider1,'Value');
handles.sliderValue=num2str(slider_value);
set(handles.edit1,'String',handles.sliderValue);
guidata(gcbo,handles);

function edit1_Callback(hObject, eventdata, handles)

editValue=str2double(get(handles.edit1,'String'));
handles.editValue=editValue;
set(handles.slider1,'Value',handles.editValue);
guidata(gcbo,handles);

ครั้งต่อไปคงเป็นตัวอย่างการประยุกต์ของ slider

Sunday, December 30, 2012

GUI MATLAB plans for 2013

หลายเดือนที่ผ่านมาผมพยายามจัดการกับการศึกษาของตัวเอง ทำให้ไม่ค่อยได้เพิ่มเติมเกี่ยวกับ Blog นี้เท่าที่ควรจะเป็น ด้วยเหตุนี้ผมควรมีแผนการพัฒนาที่ชัดเจนและเตือนสติว่าให้แบ่งเวลามาให้บ้าง ในปี พ.ศ. 2556 นี้ผมวางแผนสำหรับ Blog ไว้ดังนี้


1. ชำระบัญชีที่ค้างเรื่อง ทฤษฎีเกี่ยวกับ Color image (RGB) ให้เสร็จ
2. มุ่งศึกษาเรื่อง Video processing
3. มุ่งศึกษาเรื่อง Pattern recognition
4. ศึกษาและพัฒนา Particle tracking and Particle counting

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

(ถ้าว่างจะจัดการเรื่อง การพัฒนา GUI สำหรับเรื่อง Rutherford scattering ให้สำเร็จสี่ตอน)

Sunday, December 16, 2012

Real time image and video processing with MATLAB

ก่อนอื่นต้องรับตามตรงว่า ผมยังไม่มีความรู้เกี่ยวกับ video processing ครับก็เลยลองค้นหาดูว่าใครทำอะไร มีปัญหา หรือช่องทางช่องว่างให้เราแทรกเข้าไปทำในส่วนที่ยังขาดหายไปหรือเปล่า แต่อย่างไรก็ตามครับ ผมก็ต้องเรียนจากชาวบ้านไปก่อน ผมไปเจออยู่เวบไซต์หนึ่งครับเห็นว่าเป็นตัวอย่างที่ไม่ซับซ้อนและทำงานได้ดีครับ เวบไซต์ที่ว่าก็คือ Matlabtips.com  และตัวอย่างที่ได้ลองเอามารันดูตามนี้ครับ ลองทำเป็นวีดิโอเพื่อนับจำนวนรถที่วิ่งผ่านถนนหน้าห้องทำงานครับ ก็พอจะมองเห็นว่าโปรแกรมนี้น่าเอาไปประโยชน์อย่างอื่นได้อีก ในภาพด้านล่างมีทั้งหมดสามรูปที่ผม print screen จากคอมพิวเตอร์ส่วนตัว ภาพเล็กด้านซ้ายสุดแสดงภาพที่ capture จากวีดิโอ เมื่อยังไม่มีวัตถุวิ่งผ่าน ภาพกลางเป็นมอเตอร์ไซต์วิ่งผ่าน และขวาสุดเป็นรถยนต์ที่วิ่งผ่านไป จะเห็นว่าค่าโดยเฉลี่ยของวีดิโอเฟรมเปลี่ยนแปลงในลักษณะเป็นพีคให้เราเห็นนะครับ ถ้าพัฒนาต่อปรับทั้งโปรแกรม เครื่องมือ และวิธีการ เก็บข้อมูล ผมว่าน่าจะใช้ประโยชน์ได้ในหลายแง่มุมครับ



   
และนี่เป็นตัวอย่างในยูทูปครับ ที่เจ้าของโค๊ดเขาทำไว้ครับ





ต้องติดตามกันต่อไปว่าเราจะต้มยำทำแกงกับโปรเจ็กนี้ต่อไปอย่างไรนะครับ ไม่แน่ผมอาจจะเอาไปนับเม็ดเลือดก็ได้นะครับ (เคยส่องเม็ดเลือดแดงบริเวณหางของปลาทอง สมัยเรียน) ก็เป็นโปรเจ็กที่น่าสนใจหรือไม่ก็เอาไปให้น้องๆที่สนใจ ไปพัฒนาเล่นๆ จะได้มีโปรเจ็กทำหากใครชอบแนวนี้ หรือจะเอาไปรวมกับวิธีการตรวจจับอะไรสักอย่างร่วมกับเทคนิคอื่น เช่นวัดการวาวแสงของวัตถุ วัดด้วยเทคนิคทางไฟฟ้า สรุปหลักการใหญ่ๆ มันก็มีไม่กี่แนวคิด แต่เวลาลงมือทำนี่สิไม่ใช่เรื่องง่ายๆ หลักการที่ว่าส่วนใหญ่ต้องอาศัยวิชาฟิสิกส์ทั้งนั้นละครับ เช่น ตรวจจับด้วย แสง ไฟฟ้า (กระแสไฟฟ้า สภาพการนำไฟฟ้า ค่าความจุไฟฟ้า ...) สนามแม่เหล็ก สนามไฟฟ้า คลื่นชนิดต่างๆ เป็นต้น

 ถ้าท่านไหนคิดอะไรได้หรือพัฒนาอะไรไปบ้างก็เอาแบ่งกันชมบ้างนะคร๊าบ

Wednesday, October 3, 2012

RBS: Rutherford Backscattering Spectrometry part I

วันนี้กลับมาอ่านเรื่อง Rutherford scattering และลองเข้าไปดูใน cyber space ว่ามีใครเขียน m-file เกี่ยวกับ การทดลองเรื่องนี้บ้างก็มีอยู่พอควรเลยครับ (จริงๆแล้ว มีเยอะมากครับ แต่ผมเฉพาะเจาะจงที่พัฒนาด้วย MATLAB อย่างเดียว) ที่โดดเด่น ท่านนี้เลยครับ Javier E. Hasbun เขียนหนังสือเรื่อง "Classical Mechanics With MATLAB Applications"  เขาอัพโหลด code ในตัวอย่างหนังสือไว้ที่ ===> mathwork ถ้าสนใจลองไปติดตามกันได้
จึงจะหยิบยกเอาส่วนที่คำนวนเกี่ยวกับพลังงานของ scattered particles มาพิจารณากัน เนื่องจากว่าห่างหายไปพอควรกับ blog นี้ก็เลยถือโอกาศมาขยับกันหน่อย ในเรื่องนี้ผมยังทำ GUI เหมือนเดิมอย่าพึ่งตกใจว่าพูดถึงฟิสิกส์มากไป มีความจำเป็นที่ต้องกล่าวถึงที่มาที่ไปจริงๆครับ วางแผนไว้ว่าจะแบ่งเป็นสี่ตอนครับ ทฤษฎีสองตอน ทำ GUI สองตอนครับ (หวังไว้ว่าอย่างนั้น) กลับมาที่ Rutherford scattering กันต่อ เราจะเริ่มด้วยการพิจารณา


$\textbf{Kinematics of Elastic Collisions}$

สำหรับ RBS นั้นเราจะเริ่มต้นด้วย การระดมยิ่งด้วย ไอออนที่มีพลังงานค่าเดียว (Monoenergetic particles) ไปยัง อะตอมของธาตุเป้า (Target atoms) เราเรียกไอออนที่เข้าไปชนว่า Incident ions หรือ Projectile ions ภาษาไทยขอเรียกว่า ไอออนกระสุน ตามเอกสารอ้างอิง [1] หลังจากชนแล้วไอออนกระสุนบางตัวจะกระเจิงกลับหลัง (Back scattering) มาตกกระทบที่หัววัด ทำให้ทราบว่าไอออนตัวนั้นกระเจิงออกมาแล้วเหลือพลังงานเท่าไร หลักการของหัววัดจะกล่าวถัดไป รูปด้านล่างเป็นการจัดชุดการทดลอง RBS

                                       
                            รูปที่ 1 ลักษณะการจัดวางเครื่องมือสำหรับการทดลอง RBS (บน) และ Elastic collision รูปนี้เขียนมาจาก เอกสารอ้างอิงที่ [2]

จากรูป ไอออนกระสุนมีมวล ความเร็ว และพลังงานเป็น $M_{1},\;v_{0}$ และ $E_{0}$ วิ่งเข้าไปชน อะตอมของธาตุเป้าที่อยู่นิ่ง มีมวลเป็น $M_{2}$ หลังจากชน ไอออนกระสุนกระเจิงกลับหลังด้วยมุม $\theta$ เรียกว่า Scattering angle โดยมีความเร็วและพลังงานเป็น $v_{1}$ และ $E_{1}$ ส่วนอะตอมของธาตุเป้า เคลื่อนที่ถอยหลังไปด้วยมุม $\phi$ มีความเร็วและพลังงานเป็น $v_{2}$ และ $E_{2}$ เรียก ว่า Recoil atom

การพิจารณาการถ่ายโอนพลังงานของการชนแบบไม่ยืดหยุ่น จะอาศัยกฎการอนุรักษ์พลังงาน และกฎการอนุรักษ์โมเมนตัม ซึ่งสามารถเขียนออกมาเป็นสมการดังนี้

$ (1)\;\;\;\;\;\;\;\;\;\; \frac{1}{2}M_{1}v_{0}^{2}=\frac{1}{2}M_{1}v_{1}^{2}+\frac{1}{2}M_{2}v_{2}^{2} $

$ (2)\;\;\;\;\;\;\;\;\;\;M_{1}v_{0}=M_{1}v_{1}cos\theta +M_{2}v_{2}cos\phi $

$ (3)\;\;\;\;\;\;\;\;\;\;0=M_{1}v_{1}sin\theta-M_{2}v_{2}sin\phi $

จากนั้นเราจะหาค่าอัตราส่วน $\frac{E_{1}}{E_{0}}$ หรือเรียกว่า $Kinematic\;factor\;\;K=\frac{E_{1}}{E_{0}}$

เริ่มจากกำจัดตัวแปร $\phi$ ทิ้งก่อน โดยการ ยกกำลังสองของสมการ 2 และ 3 แล้วจับมาลบกันจะได้สมการดังนี้

$ (4)\;\;\;\;\;\;\;\;\;\;M_{1}^{2}v_{0}^{2}=M_{2}^{2}v_{2}^{2}-M_{1}^{2}v_{1}^{2}+2M_{1}^{2}v_{0}v_{1}cos\theta$

จัดรูปใหม่ เพื่อกำจัด $v_{2}$ โดยเขียนสมการได้ดังนี้

$ (5)\;\;\;\;\;\;\;\;\;\;M_{2}^{2}v_{2}^{2}=M_{1}^{2}v_{1}^{2}+M_{1}^{2}v_{0}^{2}-2M_{1}^{2}v_{0}v_{1}cos\theta$

จากนั้นนำสมการที่ 5 ไปแทนในสมการที่ 1 จะได้สมการดังนี้

$ (6)\;\;\;\;\;\;\;\;\;\;M_{1}v_{0}^{2}=M_{1}v_{1}^{2}+\frac{M_{1}^{2}}{M_{2}}v_{0}^{2}+\frac{M_{1}^{2}}{M_{2}}v_{1}^{2}-2\frac{M_{1}^{2}}{M_{2}}v_{0}v_{1}cos\theta$

จากนั้น หารตลอดด้วย $M_{1}v_{0}^{2}$ และจัดรูปเป็นสมการกำลังสอง ได้ดังนี้

$ (7)\;\;\;\;\;\;\;\;\;\;0=(1+\frac{M_{1}}{M_{2}})(\frac{v_{1}}{v_{0}})^2-(\frac{2M_{1}cos\theta}{M_{2}})(\frac{v_{1}}{v_{0}})+(\frac{M_{1}}{M_{2}}-1)$

จากนั้นก็แก้สมการกำลังสอง จะได้คำตอบคือ

$ (8)\;\;\;\;\;\;\;\;\;\;\frac{v_{1}}{v_{0}}=\frac{M_{1}cos\theta}{M_{1}+M_{2}}\pm [(\frac{M_{1}}{M_{1}+M_{2}})^2cos^2\theta+(\frac{M_{2}-M_{1}}{M_{1}+M_{2}})]^{1/2}$

หรือ

$ (9)\;\;\;\;\;\;\;\;\;\;\frac{v_{1}}{v_{0}}=\frac{M_{1}cos\theta\pm[M_{2}^{2}-M_{1}^{2}sin^2\theta]^{1/2}}{M_{1}+M_{2}}$

สำหรับอัตราส่วนของพลังงาน เมื่อ $M_{1}<M_{2}$ จะเขียนได้ว่า

$ (10)\;\;\;\;\;\;\;\;\;\;\frac{E_{1}}{E_{0}}=[\frac{M_{1}cos\theta+[M_{2}^{2}-M_{1}^{2}sin^2\theta]^{1/2}}{M_{1}+M_{2}}]^2$

 โดยที่ $Kinematic\;factor,\;K=[\frac{M_{1}cos\theta+[M_{2}^{2}-M_{1}^{2}sin^2\theta]^{1/2}}{M_{1}+M_{2}}]^2$

ดังนั้น $E_{1}=KE_{0}$ หากย้อนไปพิจารณาสมการที่ 10 จะเห็นว่าพารามิเตอร์ $E_{0},\;E_{1}$ วัดได้โดยตรงจากหัววัด มุม $\theta$ เซตได้จากการทดลอง $M_{1}$ รู้อยู่แล้วในทางปฏิบัติจาก switching magnet (คัดเลือกมวลและประจุ) หรือใช้แหล่งกำเนิดที่รู้ชนิดของอนุภาคเช่น Alpha source (แต่คงต้องเป็นแหล่งกำเนิดที่แรงหน่อย) ดังนั้นจะเห็นว่าการทดลองนี้สามารถหา องค์ประกอบของตัวอย่างว่าประกอบด้วยธาตุอะไรบ้าง รายละเอียดติดตามได้จากเอกสารอ้างอิง (Refs. 1 และ 2)

ในตอนนี้ต้องจบไว้แค่นี้ครับ แล้วจะมาต่อในตอนถัดไป

References

[1] รองศาสตราจารย์ ดร. สมศร สิงขรัตน์ และ ดร. ธีรศักดิ์ คำวรรณะ, คู่มือแนะนำ เทคนิค RBS, RBS/channeling, PIXE และ IL: 4 เทคนิควิเคราะห์ธาตุด้วยลำไอออนในระดับไมโครเมตรและนาโนเมตร, ศูนย์วิจัยฟิสิกส์ของพลาสมาและลำอนุภาค, ภาควิชาฟิสิกส์และวัสดุศาสตร์ คณะวิทยาศาสตร์ มหาวิทยาลัยเชียงใหม่ 2553

[2] Terry L. Alford, Leonard C. Feldman and James W. Mayer. Fundamentals of Nanoscale Film Analysis, Springer 2007.

Thursday, August 30, 2012

Mean Square Displacement (MSD)


MSD Part I หลักการเบื้องต้นและเครื่องมือที่จำเป็นสำหรับการหา MSD ในงานเชิงชีวฟิสิกส์ อ่านรายละเอียดเพิ่มเติม >>> MSD I
MSD Part II
ทฤษฏีเริ่มต้นด้วย One-dimensional random walk เพื่อพาไปสู่สมการ mean square displacement ซึ่งมีรายละเอียดเกี่ยวกับความเข้าใจในเรื่อง diffusion ที่น่าจะมีพื้นฐานความเข้าใจไว้เบื้องต้น อ่านรายละเอียดเพิ่มเติม >>> MSD II
MSD Part III
ขั้นตอนและวิธีการเชิงเทคนิคเพื่อหาค่า MSD exponent ซึ่งเป็นค่าที่ใช้บ่งบอกพฤติกรรมของอนุภาคที่เคลื่อน อ่านรายละเอียดเพิ่มเติม >>> MSD III
MSD Part IV
ขั้นตอนการทำ MSD program โดยยืนบนพื้นฐาน GUI ของ MATLAB เพื่อใช้คำนวนหา MSD exponent อ่านรายละเอียดเพิ่มเติม >>> MSD IV

Tuesday, July 24, 2012

Image processing & Mean square displacement (MSD) part IV (GUI MATLAB)

ขาดหายไปนานสำหรับหัวข้อนี้ ตอนแรกคิดไว้จะให้เสร็จสิ้นในตอนที่ 4 นี้แต่ทว่าตัวโปรแกรมยังไม่สมบูรณ์ครับ ด้วยเหตุผลที่ผมต้องไปทำงานหลักที่สำคัญกับชีวิตผม จึงจำเป็นที่ต้องเขียนทั้งๆที่มันไม่สมบูรณ์นี่แหละ ผมต้องย้อนไปสักนิด ว่าการหา MSD นั้นในที่นี้ผมจะใช้ โปรแกรม SpotTracker ซึ่งเป็น plug-in ของ ImageJ ในการหาตำแหน่งของอนุภาคที่เราสนใจจากนั้น เอาตำแหน่งมาคำนวนหา MSD โดยใช้ source code ที่ช่วยๆ กันเขียนขึ้นกับเพื่อนและรุ่นพี่สมัยเรียน แต่ผมจับมาใส่ใน GUI MATLAB

รูปร่างหน้าตาโปรแกรมก็จะประมาณนี้ ครับ


ตัวโปรแกรมจะถูกแบ่งหน้าที่การทำงานเป็น 3 ส่วน ได้แก่

1. ส่วน Image processing ส่วนนี้คงต้องเป็นโปรเจกยาว เพราะต้องการให้มีหน้าที่ ทำได้ทั้งรูปและวิดิโอ รวมไปถึง การทำ tracking ด้วย ตอนนี้เอาไว้แสดง วีดิโอและภาพเท่านั้น

2. ส่วนแสดง Random walk แบบ 2 มิติ

3. ส่วนการคำนวน ประกอบด้วย ส่วนแสดงเส้นทางการเคลื่อนที่ของอนุภาค (Trajectory), velocity correlation และการคำนวน MSD exponent

-หากเป็นตำแหน่งของ Random walk จาก simulation เมื่อเลือก MSD cal. check box โปรแกรมจะคำนวน MSD exponent ให้
-หากจะคำนวน MSD exponent ของอนุภาคต้อง load positions ที่ได้จาก SpotTracker เข้ามาก่อนถึงจะคำนวนได้

หัวข้อนี้เนื้อหาสั้นครับ แต่โปรแกรมยาวพอควร หากผมต้องการพักสมองจากงานหลักเมื่อใดคงจะมาพัฒนาส่วนที่ยังขาดครับ งานนี้ไม่ง่ายเลยสำหรับผม แต่เชื่อว่าสักวันต้องเสร็จ 555 !

ไฟล์ต่างเข้าไปโหลดในนี้ได้เลย ImageProMSD

Tuesday, July 3, 2012

How to interface webcam with MATLAB

    วันนี้ข้ามมาเขียนเรื่องนี้ก่อนครับ มีน้องท่านหนึ่ง เขามาฝากข้อความไว้ ว่าสนใจเรื่องการติดต่อ Web camera แล้วให้มาแสดงผลใน GUI ของ MATLAB ตัวผมก็ไม่เคยทำเอาละว้าจะเริ่มไงก่อนดีละเนี่ย

    ปัจจุบันเทคโนโลยีด้านอิเล็กทรอนิกส์เจริญขึ้นอย่างรวดเร็ว ผลก็คือ เราก็มีเทคโนโลยีที่ดี และราคาถูกลง เช่นกันด้าน soft ware ก็มีการพัฒนาไปมาก เช่นโปรแกรมด้าน image processing ที่มีความสามารถหลากหลาย ก็แถมติดมากับแผ่น driver กล้อง web camera เลยก็ยังมี อีกทั้ง smart phone สมัยนี้มาแรงจริงๆครับ เทคโนโลยีของเขาถือว่าก้าวล้ำนำสมัย แต่ถ้าเรานั่งใช้นั่งรอเขาทำของใหม่ๆมาให้เราใช้ก็สะดวกอีกแบบครับ แต่ถ้าเราพอจะมีความรู้อยู่บ้าง และความต้องการด้าน soft ware ที่เฉพาะเจาะจง เพื่อให้เข้ากับงานของเรา การพัฒนาขึ้นใช้เองก็เป็นอีกทางออกหนึ่งครับ คิดเสียว่าเหมือนเราเขาโรงเรียนตอนเด็กยังไงทุกคนก็เริ่มจาก หัดท่องหัดเขียน (ก ข, a b c) เหมือนๆ กันครับ ไม่เป็นไรของแพงย่อมต้องดีอยู่แล้ว แต่ของที่ทำขึ้นเองก็ต้องดีในแบบฉบับของเราและแน่นอนมันภูใจครับ แต่หากท่านใดต้องการความสะดวกรวดเร็ว  และมีกำลังทรัพย์ผมถือว่าเป็นความได้เปรียบอย่างหนึ่งครับ
    กลับมาที่น้องเขาฝากข้อความไว้ (ไม่รู้จะกลับมาดูอีกไหม) ก็ประจวบเหมาะที่ผมเคยซื้อเจ้า webcam (Oker, web camera 177) มาไว้ใช้งานเก็บข้อมูลบางอย่าง ไว้นานแล้วเหมือนกัน ตอนนั้นผมใช้ soft ware ทั่วไปที่มีแจกกันใน cyber space ผมก็คิดไปคิดมา ว่าจะเริ่มยังไง เพราะไม่เคยทำมาก่อน สุดท้ายก็ลองมั่ว กันสักพักแต่ก็โชคดีที่หา key word ได้ถูกเลยค้นได้ง่ายหน่อย ผมค้นสองทาง ทางแรกใน internet และทางที่สอง MATLAB Help เว็บไซต์หนึ่งที่ผมเข้าไปดูและ ขอขอบคุณไว้ตรงนี้  Video & Image Acquisition using MATLAB

ก่อนอื่นผมใช้คำสั่งพวกนี้ครับ เพื่อตรวจสอบที่เกี่ยวกับข้อมูลวิดีโอ

>> imaqhwinfo('winvideo')

ans =

       AdaptorDllName: [1x81 char]
    AdaptorDllVersion: '3.2 (R2008b)'
          AdaptorName: 'winvideo'
            DeviceIDs: {[1]  [2]  [3]}
           DeviceInfo: [1x3 struct]
ปรากฏว่าพบ Devices สามตัวด้วยกัน ผมก็ตรวจดูทีละตัวว่าตัวไหนกำกับด้วย DeviceID อะไร
ในที่นี้ Oker 177 กำหนดเป็นตัวที่ 2 ก็ลองตรวจดูรายละเอียด ก็อย่างที่เห็นด้านล่างเลยครับ

>> dev2=imaqhwinfo('winvideo',2)

dev2 =

          DefaultFormat: 'RGB24_640x480'
    DeviceFileSupported: 0
             DeviceName: 'USB Video Device'
               DeviceID: 2
      ObjectConstructor: 'videoinput('winvideo', 2)'
       SupportedFormats: {1x18 cell}

จากนั้นผมก็คำสั่ง videoinput เพื่อเตรียม video ให้กับ object ของเราในที่นี้ให้ชื่อว่า vid ส่วน winvideo
นั้นเป็นชื่อ adapter ที่ใช้ติดต่อกับ webcam ส่วนเลข 2 ก็เป็น device ID จากนั้นใช้คำสั่ง preview เพื่อแสดง video

>> vid=videoinput('winvideo',2);
>> preview(vid);


จากนั้นก็ลองทำ GUI ขึ้นมาหน้าตาประมาณนี้ จุดประสงค์ของ GUI นี้คือ แสดง video ที่รับมาจาก webcam สามารถ capture เป็นรูปภาพได้พร้อมจัดเก็บ มีชุดประมวลผลด้านภาพ หรือ วิดีโอ (คงต้องเพิ่มเติมทีหลัง ตอนนี้ยังไม่มีปัญหาที่ชัดเจนว่าจะเอาไปใช้แก้ปัญหาอะไร)



ในเบื้องต้นยังไม่ได้พัฒนาอะไรเลย แค่ติดต่อ webcam แล้ว capture ภาพนิ่งเท่านั้น เวอร์ชันต่อไปคงทำส่วนของ processing ครับ



สำหรับไฟล์ต่างที่แสดงในนี้ หากใครสนใจจะลองเอาไปเป็นแนวทางหรือเอาไปพัฒนาต่อ ตามลิ้งนี้เลย Download files>>> webcam1

ในส่วนของคำสั่งที่จะปรากฏใน m-file มีรายละเอียดหลัก มีดังนี้


% --- Executes on button press in disconnect.
function disconnect_Callback(hObject, eventdata, handles)
% hObject    handle to disconnect (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
closepreview

% --- Executes on button press in connect.
function connect_Callback(hObject, eventdata, handles)
% hObject    handle to connect (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
axes(handles.axes1);

check1=get(handles.Camera1,'value');
check2=get(handles.Camera2,'value');
check3=get(handles.Camera3,'value');

if (check1==1)
obj=videoinput('winvideo',1);
elseif (check2==1)
obj=videoinput('winvideo',2);
else
obj=videoinput('winvideo',3);
end

vidRes = get(obj, 'VideoResolution'); % Resolution of device ex. 640x480
nBands = get(obj, 'NumberOfBands'); % number of channels ex. 3=RGB image
hImage = image( zeros(vidRes(2), vidRes(1), nBands) );
preview(obj, hImage);

handles.objVideo=obj;
guidata(hObject, handles);

% --- Executes on button press in capture.
function capture_Callback(hObject, eventdata, handles)
% hObject    handle to capture (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
axes(handles.axes3);
im=getsnapshot(handles.objVideo);
handles.image=im;
imshow(handles.image);
%delete(handles.objVideo);% clear memory
guidata(hObject, handles);

% --- Executes on selection change in listbox1.
function listbox1_Callback(hObject, eventdata, handles)
% hObject    handle to listbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
files = dir(fullfile(theFolder, '*.jpg'));
set(handles.listbox1, 'string', {files.name})
% Hints: contents = get(hObject,'String') returns listbox1 contents as cell array
%        contents{get(hObject,'Value')} returns selected item from listbox1


% --- Executes during object creation, after setting all properties.
function listbox1_CreateFcn(hObject, eventdata, handles)
% hObject    handle to listbox1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    empty - handles not created until after all CreateFcns called

% Hint: listbox 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 save.
function save_Callback(hObject, eventdata, handles)
% hObject    handle to save (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
%current_image=handles.image;
imsave

% --- Executes on button press in CloseWindow.
function CloseWindow_Callback(hObject, eventdata, handles)
% hObject    handle to CloseWindow (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
close(ancestor(hObject,'figure'))


% --- Executes on button press in Camera1.
function Camera1_Callback(hObject, eventdata, handles)
% hObject    handle to Camera1 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of Camera1


% --- Executes on button press in Camera2.
function Camera2_Callback(hObject, eventdata, handles)
% hObject    handle to Camera2 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of Camera2


% --- Executes on button press in Camera3.
function Camera3_Callback(hObject, eventdata, handles)
% hObject    handle to Camera3 (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)

% Hint: get(hObject,'Value') returns toggle state of Camera3


% --- Executes on button press in processingUnit.
function processingUnit_Callback(hObject, eventdata, handles)
% hObject    handle to processingUnit (see GCBO)
% eventdata  reserved - to be defined in a future version of MATLAB
% handles    structure with handles and user data (see GUIDATA)
process_check=get(handles.processingUnit,'value');
if (process_check==1)
setappdata(0, 'cap_image', handles.image);% ?????????????????? handles.dataShow ????? test_data
ImagePro;
end% open externalTable GUI
% Hint: get(hObject,'Value') returns toggle state of processingUnit

Tuesday, June 19, 2012

Image processing & Mean square displacement (MSD) part III

          ในส่วนนี้จะกล่าวถึงวิธีการ ขั้นตอน เพื่อให้ได้มาซึ่ง MSD ของระบบที่เราสนใจ

รูปที่ 1: (ก) แสดงเส้นทางการเดินของ Random walker ในสองมิติ เส้นทึบแสดงการกระจัดที่เป็น single step และเส้นประแสดงการกระจัดที่เป็น double step,  (ข) กราฟระหว่าง time intervals กับ square displacements  และ (ค) แสดง linear fit เพื่อดูว่า diffusion exponent เป็นเท่าไรเพื่อนำไปแปลความหมายต่อไป (รูปที่1 ยกมาจาก Ref. [1] ขอกราบขอบพระคุณมา ณ ที่นี้)
           ในรูปที่1 (ก) นั้น ในทางเทคนิคก็จะเป็นภาพหรือวิดิโอที่ผู้ศึกษา ถ่ายบันทึกการเคลื่อนที่ของอนุภาค แล้วใช้โปรแกรม particle tracking มาช่วยหาตำแหน่งอนุภาคที่เราสนใจ ก่อนที่จะไปถึงกระบวนค้นหา MSD นั้นขอหยิบยกรายละเอียดทางเทคนิคของ MSD มากล่าวอีกครั้งหนึ่ง
          พิจารณารูปที่1 (ก) จากตำแหน่งที่ 1 ไปยังตำแหน่งที่  2 และถัดไปมีเวลาห่างกันเป็น $\Delta {t}$ ซึ่งเรียกว่า lag time จากนั้นลองหาค่า displacement ที่ lag time เท่ากับ $\Delta {t}$

$\; \; \; \; \; \; \; \; \; \;x_{1}=x(t_{1})\; \; \; \; \; \; \; \; \; \; x_{2}=x(t_{1}+\Delta{t}) \; \; \; \; \; \; \; \; \; \; \Delta x_{1}(\Delta t)=x_{2}-x_{1}$

$\; \; \; \; \; \; \; \; \; \; y_{1}=y(t_{1})\; \; \; \; \; \; \; \; \; \; y_{2}=y(t_{1}+\Delta{t})\; \; \; \; \; \; \; \; \; \; \Delta y_{1}(\Delta t)=y_{2}-y_{1}$

$\; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; $


$\; \; \; \; \; \; \; \; \; \; x_{i}=x(t_{i})\; \; \; \; \; \; \; \; \; \; x_{i+1}=x(t_{i}+\Delta{t})\; \; \; \; \; \; \; \; \; \; \Delta x_{i}(\Delta t)=x_{i+1}-x_{i}$

$\; \; \; \; \; \; \; \; \; \; y_{i}=y(t_{i})\; \; \; \; \; \; \; \; \; \; y_{i+1}=y(t_{i}+\Delta{t})\; \; \; \; \; \; \; \; \; \; \Delta y_{i}(\Delta t)=y_{i+1}-y_{i}$

ดังนั้นค่า square displacement ก็สามารถได้ว่า

สำหรับ single lag time $\Delta t$

$\; \; \; \; \; \; \; \; \; \; (\Delta r_{i}(\Delta{t}))^{2}=(\Delta x_{i}(\Delta{t}))^{2}+(\Delta y_{i}(\Delta{t}))^{2}$

สำหรับ double lag time $\Delta t$

 $\; \; \; \; \; \; \; \; \; \; (\Delta r_{i}(\Delta{t}))^{2}=(\Delta x_{i}(\Delta{t}))^{2}+(\Delta y_{i}(\Delta{t}))^{2}$

 $\; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \; \;$

สำหรับ n lag time $n\Delta t$

$\; \; \; \; \; \; \; \; \; \; (\Delta r_{i}(\Delta{t}))^{2}=(\Delta x_{i}(\Delta{t}))^{2}+(\Delta y_{i}(\Delta{t}))^{2}$

และค่า mean square displacement ตลอดการเคลื่อนที่สำหรับ single lag time $\Delta{t}$ สามารถเขียนได้เป็น

$\; \; \; \; \; \; \; \; \; \; \left \langle (\Delta r_{i}(\Delta{t}))^{2} \right \rangle=\frac{1}{n}\left ( (\Delta r_{1}(\Delta{t}))^{2}+(\Delta r_{2}(\Delta{t}))^{2}+\Delta r_{3}(\Delta{t}))^{2}+\cdots  \right )=\frac{1}{n}\sum_{i=1}^{n}r_{i}^{2}(\Delta t)$

          ในทำนองเดียวกันนะครับ ถ้าเป็น double step ในช่วงเวลา $2\Delta t$ หรือจะเป็น $3\Delta t$, $4\Delta t$ ซึ่งจะให้ได้ข้อมูล MSD เหมือนในรูปที่ 1 (ข)

ขอยกสมการในเอกสารการศึกษาของ Kanthang และคณะ [3]  ที่หาค่า MSD สำหรับตลอดเส้นทางการเคลื่อนที่ของโปนตีนชนิดหนึ่งซึ่งอยู่ในแบคทีเรียที่ชื่อว่า E. coli

$\; \; \; \; \; \; \; \; \; \;\left \langle (\Delta r)^2 \right \rangle=\frac{1}{N-1-n}\sum_{i=1}^{N-1-n}\left \{ \left [ x(i\Delta t+n\Delta t)-x(i\Delta t) \right ]^2 + \left [ y(i\Delta t+n\Delta t)-y(i\Delta t) \right ]^2 \right \}$

โดยที่
$N$ คือ the total number of frames, $n$ คือ the number of the time interval ซึ่งเกี่ยวข้องกับ lag time

และ $i$ คือ the positive integer



References

[1]  Jakob C. Schweizer, January 26, 2007. Practical Course: Single-Particle-Tracking. 
[2] M.J. Saxton, K. Jacobson, "SINGLE-PARTICLE TRACKING: Applications to Membrane Dynamics" Annu. Rev. Biophys. Biomol. Struct. 26, 373 (1997)
[3] Kanthang P, Ngamsaad W, Nuttavut N, Triampo W, Triampo D, Krittanai C, "Biophysical approach for studying the MinD protein dynamics and energy landscape: a novel use of the spot tracking technique" European Physical Journal-Applied Physics 2011, 55(1):11201.
 [4] Unai S, Kanthang P, Junthon U, Ngamsaad W, Triampo W, Modchang C, Krittanai C, "Quantitative analysis of time-series fluorescence microscopy using a spot tracking method : application to Min protein dynamics" Biologia 2009, 64(1):27-42.
[5] D. Sage, F.R. Neumann, F. Hediger, S.M. Gasser, M. Unser, "Automatic Tracking of Individual Fluorescence Particles: Application to the Study of Chromosome Dynamics," IEEE Transactions on Image Processing, vol. 14, no. 9, pp. 1372-1383, September 2005.
[6] ImageJ, free software, available online: http://rsbweb.nih.gov/ij/