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.