Search This Blog

Showing posts with label Programming. Show all posts
Showing posts with label Programming. Show all posts

Monday, January 22, 2018

UDP/TCP Socket Programming with wxWidgets

  1. နိဒါန်း
  2. UDP
  3. TCP
  4. အကိုးအကားများ

နိဒါန်း

wxWidgets နဲ့ UDP ၊ TCP တို့ကို သုံးပြီး network ပေါ်မှာ ဒေတာ အပြန် အလှန် ပေးပို့ ဆက်သွယ် တဲ့ အကြောင်း ဆွေးနွေး ချင် ပါတယ်။ အဲဒီ အတွက် wxWidgets ကို တပ်ဆင် ထားဖို့ လိုပါ တယ်။ သူ့ကို platform အမျိုးမျိုး အတွက် တပ်ဆင်တဲ့ အကြောင်း တွေကို အောက်က လင့်ခ် မှာ ဖတ်နိုင် ပါတယ်။
အင်တာနက် စတဲ့ network တွေ ပေါ်မှာ TCP ဒါမှမဟုတ် UDP တွေသုံးပြီး စက်တစ်ခု နဲ့ တစ်ခု ဒေတာ တွေ အပြန်အလှန် ပို့ဖို့ အတွက် socket တွေကို အသုံးပြု နိုင် ပါတယ်။ ခေတ်ပေါ် operating system တွေ အားလုံးက socket layer ကို အထောက် အပံ့ ပေးကြ ပေမယ့် platform ပေါ်မူ တည်ပြီး socket ကို အသုံး ပြုရတဲ့ ပုံစံ တွေက အမျိုးမျိုး ကွဲပြား နိုင်ပါတယ်။ wxWidgets မှာ အောက်ခံ platform အတွက် ပူစရာ မလိုပဲ အလွယ် တကူ အသုံးပြုနိုင်တဲ့ socket class ပါ ပါတယ်။ အဲဒီ class ကို မတူညီတဲ့ ပုံစံ နည်းလမ်း အမျိုးမျိုး နဲ့ အသုံးပြုနိုင်ပြီး၊ အသုံးပြုပုံ နမူနာ တချို့ကို အောက်မှာ ဆက်ပြီး ဖော်ပြထား ပါတယ်။


Friday, October 27, 2017

Cross-platform C++ programming with wxWidgets

  1. နိဒါန်း
  2. Windows တွင်တပ်ဆင်ခြင်း
  3. Linux တွင်တပ်ဆင်ခြင်း
  4. Mac တွင်တပ်ဆင်ခြင်း
  5. အကိုးအကားများ

နိဒါန်း

wxWidgets က Windows ၊ Linux နဲ့ Mac OSX အစ​ ရှိ​တဲ့ ပ​လက်​ဖောင်း အမျိုး​မျိုး ပေါ်​မှာ GUI applications တွေ ရေး​ဖို့ အတွက် C++ library ပါ။ သူ​နဲ့ GUI code တွေ ရေး​ပြီး​ ရင် ပ​လက်​ဖောင်း အမျိုး​မျိုး ပေါ်​မှာ ကုဒ် ကို သိပ်​ပြင်​ စရာ မ​လို​ပဲ တန်း​ပြီး compile လုပ်၊ run လုပ်​လို့​ ရ​ပါ​တယ်။

wxWidgets ​က free လည်း​ပေး open source လည်း ​ဖြစ် တဲ့ software ပါ။ ကိုယ်​ပိုင် ဆော့​ဝဲ တွေ​ ထုတ်​မယ်​ ဆို​ရင် လည်း ဘာ​မှ ကန့်​သတ်​ချက်​ တွေ မ​ရှိ​ ပါ​ဘူး [wxW98]။ အဲဒါက Qt နဲ့ အဓိက ကွာခြားချက် ပါ။ Qt က LGPLv3 လိုင်စင် ကို free ပေးထားပြီး၊ ကိုယ်ပိုင် စီးပွားရေး အတွက် သုံးမယ် ဆိုရင် ကန့်သတ်ချက် တချို့ ရှိတာကြောင့် လိုင်စင် ဝယ်ဖို့ လိုကောင်း လိုနိုင် ပါတယ် [Qt17]။

Native platform ကို တတ်နိုင် သလောက် သုံးထား တာမို့ wxWidgets သုံးလို့ ရလာတဲ့ GUI တွေဟာ သုံးတဲ့ platform နဲ့ လိုက်ဖက်ပြီး ပင်ကို အမြင် အတိုင်း တသားထဲ ကျ တာကို ခံစား ရမှာပါ [wxW12]။ Standard C++ ကိုပဲ သုံးထားပြီး Qt တို့လို အထူး extension တွေ မသုံးထား တဲ့ အတွက် ရှုပ်ထွေးမှု နည်းတာ ကလည်း ကောင်းတဲ့ အချက် တစ်ခုပါ။

wxWidgets နဲ့ ရလာတဲ့ binary application တွေဟာ သေးငယ် ပေါ့ပါး တာမို့ embedded system တွေအတွက် အထူး သင့်တော် ပါတယ်။ နောက်တစ်ခါ library အရွယ်အစား တွေ ယှဉ်ရင်လည်း ဥပမာ အနေနဲ့ Qt library ကို တပ်ဆင်ရင် \(\approx 200\) MB လောက် အရွယ် ရှိပေမယ့် wxWidgets library က \(\approx 30\) MB လောက်ပဲ ယူပါတယ်။

wxWidgets က C++ အတွက် သာ မကပဲ python, perl, php, java, lua, lisp, erlang, eiffel, C# (.NET), BASIC, ruby နဲ့ javascript အတွက် တောင်မှ bindings [wxW15a] တွေ ရှိပါတယ်။ wxWidgets က တော်တော် ပြည့်စုံ ရင့်ကျက် တဲ့ GUI toolkits ဖြစ်ပြီး၊ utility classes လည်း အများကြီး ရှိတာမို့ ကောင်းမွန် သင့်တော် တဲ့ GUI toolkits အနေနဲ့ ညွှန်းဆို ချင်ပါတယ်။

wxWidgets ကို အသုံးပြုတဲ့ သူတွေ၊ အဖွဲ့အစည်းတွေ အများကြီး ရှိပြီး အဲဒီ အထဲမှာ လူသိများ တာတွေက NASA, AMD, Xerox, နဲ့ Open Source Applications Foundation (OSAF) တို့ ဖြစ်ပါတယ်။ ထင်ရှားတဲ့ wxWidgets applications တွေက AVG AntiVirus, Audacity, Filezilla, Code::Blocks, CodeLite တို့ ဖြစ်ပါတယ်။

Tuesday, June 6, 2017

Flash content protection for LPC824

LPC824 low cost 32-bit ARM Cortex-M0 microcontroller လေးကို OM13071 LPCXpresso824-MAX Development board သုံးပြီး evaluate လုပ်လို့ရတဲ့ အတွေ့အကြုံလေးကို ပြောချင်ပါတယ်။ Board မှာ သုံးထားတဲ့ MCU အမျိုးအစားက LPC824M201JHI33 ပါ။ အရွယ်အစား က 5 x 5 x 0.85 mm ပဲရှိတဲ့ 33 pins ပါတဲ့ HVQFN package ပါ။

သူ့အတွက် MCUXpresso Integrated Development Environment (IDE) ကို download လုပ်ပြီး၊ install လုပ်ပါမယ်။ အခြား လိုအပ်တဲ့ tools တွေကိုလည်း ဒီမှာ တွေ့နိုင်ပါတယ်။ MCUXpresso ကိုဖွင့် ပြီး workspace သတ်မှတ်ပြီးတဲ့ အခါ ဘယ်ဘက်အောက်နားက Quick Start Paner ထဲက Import projects from file system ... ဆိုတာကိုနှိပ်ပြီး Browse LPC open resources ကိုနှိပ်ပြီး နမူနာ တွေကို ယူနိုင်ပါတယ်။



Wednesday, May 31, 2017

Programming serial port in C++ with wxWidgets for Windows and Linux

Seriar Port ကိုအသုံးပြုနိုင်တဲ့၊ ကျနော်ဖန်တီးထားတဲ့ C++ class library လေးတစ်ခု အကြောင်း ပြောချင်ပါတယ်။ သူက cross-platform ဖြစ်ပြီး Windows ရော၊ Linux မှာပါ သုံးနိုင်ပါတယ်။ နမူနာ အနေနဲ့ ရိုးရှင်းတဲ့ C++ console program လေးတစ်ခုကို ဖော်ပြထားပြီး၊ GUI application အနေနဲ့ wxWidgets ကိုသုံးထားတဲ့ program ကိုပါ ဖော်ပြထားပါတယ်။ သူတို့ရဲ့ source code တွေကို အောက်က လင့်ခ် မှာ တွေ့နိုင်ပါတယ်။

https://github.com/yan9a/serial


Figure. A wxWidgets GUI application using 'Serial' class with Visual Studio 2017

Thursday, January 21, 2016

Mesh Bee - JN5168

Mesh Bee က NXP ကထုတ်တဲ့ JN516x wireless chip ကိုသုံးပြီး seeed studio ထုတ်တဲ့ 2.4GHz wireless transceiver ပါ။ ကောင်းတာ တခုက သူက လုံးဝ open hardware, open source ပါ။ NXP ကပေးတဲ့ development environment နဲ့ tools တွေကလည်း free ရပါတယ်။

Tuesday, November 17, 2015

Driving 28BYJ-48-5V Stepper Motor with ULN2003A Transistor Arrays on Arduino

28BYJ-48-5V Stepper Motor နဲ့ ULN2003A driver တွေက တော်တော် အသုံးများပုံရပြီး အလွယ်တကူ ဝယ်နိုင်ရုံတင်မက စျေးလည်း တော်တော်ပေါ ပါတယ်။ Stepper Library ကို မသုံးပဲ Arduino ရဲ့ Port B ကို သုံးပြီး Stepper motor ကို ထိန်းတဲ့ ရိုးရှင်းတဲ့ နမူနာလေး ဖော်ပြချင်ပါတယ်။


Figure. Driving 28BYJ-48-5V Stepper Motor with Arduino UNO using USB power.


28BYJ-48-5V Stepper Motor က 5V နဲ့ တိုက်ရိုက်မောင်းနိုင်ပြီး၊ unipolar stepper motor အမျိုးအစားပါ။ သူ့ရဲ့ schematic ကို အောက်မှာပြထားပါတယ်။


Figure. 28BYJ-48-5V Stepper Motor.


ULN2003A Transistor Arrays ကတော့ inductive load တွေကို drive လုပ်ဖို့ ဒီဇိုင်းလုပ်ထားတာမို့ အထဲမှာ free wheeling diode ပါ ပါ ပါတယ်။ Darlington pair သုံးထားတာမို့ အဝင် ဗို့ 1.4V လောက်ကနေ 30V အထိ ကြိုက်တဲ့ ဗို့နဲ့ တိုက်ရိုက်ဆက်ပြီး ထိန်းနိုင်ပါတယ်။


Figure. ULN2003A.


Wave drive, Full step drive နဲ့ Half step drive တွေကို သုံးပြထားတဲ့ နမူနာ ပရိုဂရမ် လေးကို အောက်မှာ ပြထားပါတယ်။


//Driving 28BYJ-48-5V Stepper Motor using ULN2003A Transistor Arrays
//Author: Yan Naing Aye
//Website: http://www.cool-emerald.com/

#include "StepperPortB.h"
//----------------------------------------------------------
void setup() {    
  StepperInit();//setup pins
  //StepperMode(WAVE);
  //StepperMode(FULL);
  StepperMode(HALF);
  //Serial.begin(9600);
}
void loop() {
  Step(4096,2500); //turn 4096 steps forward with 2500 us period for each step
  Step(-4096,2500);//turn 4096 steps backward with 2500 us period for each step
  //Serial.println(CS);
}


//File: StepperPortB.h
//Author: Yan Naing Aye
//Website: http://www.cool-emerald.com/

//Driving 28BYJ-48 – 5V Stepper Motor using ULN2003A Transistor Arrays
//----------------------------------------------------------
#ifndef StepperPortB_h
  #define StepperPortB_h
  #include "Arduino.h"
byte* S; //Stepping sequence

//Wave drive
//Step          0 | 1 | 2 | 3 | 0 |...

//Blue   = A :  1 | 0 | 0 | 0 | 1 | ...
//Pink   = B :  0 | 1 | 0 | 0 | 0 | ...
//Yellow = C :  0 | 0 | 1 | 0 | 0 | ...
//Orange = D :  0 | 0 | 0 | 1 | 0 | ...
byte Wave[4] = {0x01,0x02,0x04,0x08};

//Full Step drive
//Step          0 | 1 | 2 | 3 | 0 |...

//Blue   = A :  1 | 1 | 0 | 0 | 1 | ...
//Pink   = B :  0 | 1 | 1 | 0 | 0 | ...
//Yellow = C :  0 | 0 | 1 | 1 | 0 | ...
//Orange = D :  1 | 0 | 0 | 1 | 1 | ...  
byte FullStep[4] = {0x09,0x03,0x06,0x0C};

//Half Step drive
//Step          0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 0 |...

//Blue   = A :  1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 1 |...
//Pink   = B :  0 | 0 | 1 | 1 | 1 | 0 | 0 | 0 | 0 |...
//Yellow = C :  0 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |...
//Orange = D :  1 | 0 | 0 | 0 | 0 | 0 | 1 | 1 | 1 |...
byte HalfStep[8] = {0x09,0x01,0x03,0x02,0x06,0x04,0x0C,0x08};
int CS=0;//Current step
int N;
//----------------------------------------------------------
//Mode definition
#define HALF 0
#define FULL 1
#define WAVE 2
//Define the mode to drive the stepper motor
void StepperMode(int Mode) {  
  if(Mode==WAVE) {S=Wave; N=4;}
  else if(Mode==FULL) {S=FullStep; N=4;}
  else {S=HalfStep; N=8;}
}
//----------------------------------------------------------
//Turn stepper motor n steps
//with t microseconds period for each step
//positive n for forward dir and negative n for backward dir
void Step(int n,int t) {
  int CD=1; 
  if(n<0) {n*=-1; CD=-1;}
  for(int i=0;i<n;i++) {
    CS=(CS+(N+CD))%N;
    PORTB=S[CS];
    delayMicroseconds(t);
  }
}
//----------------------------------------------------------
//Initialize
void StepperInit() {
  //Setup port B (digital pin 8 to 13)
  //The two high bits (6 & 7) map to the crystal pins and are not usable
  //only 4 pins - 8 to 11 are used in this program
  //where Blue - pin 8 (LSB), Pink -pin 9, Yellow -pin 10, Orange -pin 11
  DDRB=0xff;
  PORTB = 0x00;  
}
//----------------------------------------------------------
#endif

Monday, November 16, 2015

Fitting a curve to a function

ပေးထားတဲ့ curve တခုနဲ့ အကိုက်ညီဆံုး piecewise linear function တခုကို ရှာတဲ့ နမူနာ MatLab code တခုပါ။



%Fitting a curve to a piecewise linear function using least square method
%with the fixed start and end points

%clear command windows
clc;

%clear workspace
clear all;
%--------------------------------------------------------------------------
%Read curves
load Curve.dat;

%find lower left and upper right corners 
xD=Curve(1,:);
yD=Curve(2,:);
x0=min(xD); x1=max(xD); 
y0=min(yD);  y1=max(yD);
n=5;%order n i.e, the number of segments
FS=x1-x0;
global xs;
global yB;
global yE;
xs=(0:FS/n:FS);
yB=y0;
yE=y1;
%initialize coefficients (y values) to find 
%excluding the first and the last one
ys_initial=xs(2:n);
% options = optimset('MaxFunEvals',1000,'MaxIter',1000);
% LowerBoundC=y0;
% UpperBoundC=y1;
% ys =lsqcurvefit(@LineSeg,ys_initial,xD,yD,LowerBoundC,UpperBoundC,options);
ys =lsqcurvefit(@LineSeg,ys_initial,xD,yD);
%fixed start and end points
ys=[y0 ys y1];
%--------------------------------------------------------------------------
%Plot 
hFig1 = figure(1);
set(hFig1, 'Position', [600 100 500 300])
plot(xD,yD,':g','LineWidth',3,...
                'MarkerEdgeColor','b',...
                'MarkerFaceColor','b',...
                'MarkerSize',2)
hold on;             
plot(xs,ys,'-rs','LineWidth',1,...
     'MarkerEdgeColor','r',...
     'MarkerFaceColor','r',...
     'MarkerSize',4)
hold off;        
grid on;
%--------------------------------------------------------------------------


LineSeg.m
function [y] = LineSeg(ys,x)

global xs
global yB
global yE
L=length(x);
y=zeros(1,L);
ys=[yB ys yE];
LS=length(ys);
for i=1:L
    xt=x(i);
    %--------------------------
    %find segment
    for j=2:LS
        if(xs(j)>=xt) 
            break;
        end
    end    
    %interpolate
    x2=xs(j);
    y2=ys(j);
    y1=ys(j-1);
    x1=xs(j-1);
    y(i)=y1+(y2-y1)/(x2-x1)*(xt-x1);
    %--------------------------
end 

Friday, September 25, 2015

Adafruit CC3000 WiFi for Arduino

WiFi သုံးပြီး microcontroller နဲ့ ဆက်သွယ်တဲ့ ဟာကို Arduino Uno နဲ့ Adafruit CC3000 WiFi Shield ကိုသုံးပြီး စမ်းကြည့်ထားတာပါ။ သူက Arduino ရဲ့ standard WiFi shield မဟုတ်တဲ့ အတွက် WiFi.h library ကို သုံးလို့မရပါဘူး။ ဒါ့ကြောင့် Adafruit CC3000 library ကို ဒေါင်းလုပ်လုပ်၊ un-zip လုပ်ပြီး C:\Program Files (x86)\Arduino\libraries folder ထဲမှာ ထည့်ဖို့လိုပါတယ်။


Figure. Adafruit CC3000 WiFi shield stacked with Arduino Uno.


Wednesday, September 16, 2015

Testing Dual-Core Microcontroller - LPC54102

LPC54102J512 MCU မှာ Cortex M4 Master တစ်ခုနဲ့ Cortex M0+ Slave ဆိုပြီး core နှစ်ခုပါပါတယ်။ LPCXpresso IDE v7.9.0 ကိုသုံးပြီး multicore systems တစ်ခုကို ဖန်တီးတာ၊ debug လုပ်တာတွေကို နမူနာ တစ်ခုရေးပြီး စမ်းကြည့်တဲ့ အတွေ့အကြုံကို ပြောချင်ပါတယ်။ LPCOpen ကို ဒေါင်းလုပ်လုပ်ထားပြီး Quickstart -> Import project(s) ကို နှိပ်ပြီး import လုပ် ထားဖို့လိုပါတယ်။


Tuesday, August 4, 2015

Bluetooth Module to be Used with Microcontroller

HC-05 Master/Slave Bluetooth Module လေးက စျေးသက်သာပြီး (~SGD 16) သံုးရလွယ်တဲ့ Bluetooth module တစ်ခုဖြစ်ပြီး UART interface သံုးပါတယ်။ အဲဒီ HC-05 နဲ့ Arduino Uno microcontroller ကိုသံုးပြီး LED မီးလံုးကို ဖုန်းနဲ့ Bluetooth communication သံုးပြီး အဖွင့်၊ အပိတ် ထိန်း တဲ့ နမူနာတစ်ခု ကို ဆွေးနွေးပါမယ်။ တကယ်တော့ UART interface ပါတဲ့ ဘယ် မိုက်ကရိုကွန်ထရိုလာ မဆို သံုးလို့ရပါတယ်။


Figure. HC-05 Bluetooth module with Arduino Uno.

Monday, December 2, 2013

မြန်မာ ပြက္ခဒိန် အခါပေးရက်များ

မြန်မာ ပြက္ခဒိန်တွေမှာ ဗေဒင်နဲ့ ဆက်စပ်တဲ့ အခါပေးရက် ဥပမာ ရက်ကောင်း၊ရက်ဆိုး တွေကို ဖော်ပြလေ့ ရှိပါတယ်။ ဒီစာတမ်းမှာ အောက်ကရက်တွေနဲ့ သူတို့ကို javascript ကုဒ် သုံးပြီး ဘယ်လိုတွက်မလဲဆိုတာ ဖော်ပြပါမယ်

Tuesday, July 9, 2013

CAN bus

CAN Bus (controller area network) ဆိုသည်မှာ ဆက်သွယ်ရေး စနစ် တစ်ခုဖြစ်ပြီး မိုက်ခရိုကွန်ထရိုလာများ နှင့် အခြား အီလက်ထရွန်းနစ် ကိရိယာများကို ကွန်ပျူတာ မလိုအပ်ဘဲ အချင်းချင်း ဆယ်သွယ် နိုင်ရန် ပြုလုပ်ထားသော စနစ်ဖြစ်ပါတယ်။ CAN Bus ဟာ မက်ဆေ့ (message) အပေါ်တွင် အခြေခံသော ပရိုတိုကောလ်ဖြစ်ပြီး မော်တော်ယာဉ်များတွင် အဓိက အသုံးပြုလေ့ ရှိပေမယ့် စက်ရုံများနှင့် ဆေးဘက်ဆိုင်ရာ ကိရိယာများတွင်လည်း အသုံးပြုလေ့ ရှိပါတယ်။

Saturday, June 29, 2013

GNU Octave as an Alternative to MatLab

GNU OctaveFreeMat နဲ့ Scilab တို့က MATLAB လိုမျိုး တွက်ချက်မှုတွေ လုပ်ပေးနိုင်တဲ့ အလကားရတဲ့ free open source software တွေဖြစ်ပါတယ်။ လိုက်ရှာ ဖတ်ကြည့်တော့ GNU Octave က အကောင်းဆုံးလို့ ကြားတာနဲ့ သူ့ကို စက်ထဲမှာ ထည့်ပြီး စမ်းကြည့်တော့ တော်တော် သဘောကျ သွားပါတယ်။ GNU Octave ကို ဝင်းဒိုး ပေါ်မှာတင်ရတာ တော့ တော်တော်လွယ်ပါတယ်။ သူ့ရဲ့ Download page က ဖိုင်တွေကို ယူပြီး စက်ထဲမှာ folder တစ်ခု အနေနဲ့ ထုတ်ယူလိုက်ပါမယ်။ ပြီးရင် shortcut ဖိုင်ကို ကြိုက်တဲ့နေရာမှာ ထားပြီး သူ့ရဲ့ properties မှာ path နဲ့ icon ကို ပြင်ပေး လိုက်ရုံပါပဲ။ သူရဲ့ shortcut ကနေ Octave ကို ဖွင့်လိုက်ရင် အောက်က ပုံမှာ ပြထားတဲ့ အတိုင်း ကွန်မန်း ပေးလို့ရတဲ့ ဝင်းဒိုး ပွင့်လာပါမယ်။ အဲဒီမှာ MATLAB ကွန်မန်း တွေ တိုက်ရိုက် ရိုက်ထည့်ရင် လည်းရပါတယ်။

Wednesday, June 26, 2013

Chord-changer Javascript

I have written a Javascript program to transpose the guitar chords for a song into a different key. In the lyrics of the song, the guitar chords are supposed to be between <sup> and </sup>. You can try it at Myanmar Lyrics by clicking the Key Up and Key Down buttons. The codes are shown below.

Saturday, June 15, 2013

Algorithm, Program and Calculation of Myanmar Calendar

Read this article in English

မြန်မာ ပြက္ခဒိန် တွက်တဲ့ အခါ ပိုမို မြန်ဆန်လွယ်ကူ စေမယ့် ညီမျှခြင်းများကို တင်ပြမှာဖြစ်ပြီး၊ ပြီးခဲ့တဲ့ မြန်မာ ပြက္ခဒိန် ရက်ကိုပဲ ဖြစ်ဖြစ်၊ နောက်လာမည့် မြန်မာ ပြက္ခဒိန်ရက် ကို ကြိုပြီးပဲဖြစ်ဖြစ် ဘယ်လို တွက်မလဲ ဆိုတာ ဆွေးနွေးပါမယ်။ မြန်မာ ပြက္ခဒိန် ရက်စွဲ တစ်ခုရဲ့ မြန်မာ ခုနှစ်၊ မြန်မာလ၊ လဆန်း လဆုတ်၊ မြန်မာရက်၊ အဲဒီနှစ်က ဝါထပ် မထပ်၊ ထပ်ရင် လည်း ဝါကြီးလား၊ ဝါငယ်လား ဆိုတာ ကိုအလွယ်တကူ တွက်ထုတ်နိုင်ဖို့ ကိန်းသေတွေ၊ ဖော်မြူလာတွေ၊ တွက်ချက်ပုံ အဆင့် တွေ ကို ရှင်းရှင်းလင်းလင်း တင်ပြပါမယ်။ မြန်မာ ပြက္ခဒိန်၊ နတ္ခတ် အခေါ်အဝေါ် တွေနဲ့ မရင်းနှီးရင် တောင်မှ အလွယ် တစ်ကူ နားလည် နိုင်မှာပါ။

Monday, January 21, 2013

k-means clustering using custom distance measuring method

ကြိုက်တဲ့ အကွာအဝေး တိုင်းတဲ့ နည်းသုံးပြီး k-means clustering လုပ်ပေးတဲ့ MATLAB ဖန်ရှင် လေး တစ်ခု ရေးကြည့် ထားပါတယ်။ ဥပမာ histograms တွေကို ခွဲခြားဖို့ဆိုရင် chi-square distance ကို သုံးတာက ပိုကောင်း ချင် ကောင်းနိုင်ပါတယ်။ အောက်က နမူနာမှာ chi-square distance သုံးထားတာကို ပြထားပေမယ့် အဲဒီ distance ဖန်ရှင်နေရာမှာ ကိုယ်ကြိုက်တဲ့ နည်း ကို အစားထိုးပြီး သုံးလို့ရပါတယ်။

%k-means test program
X = [randn(100,2)+ones(100,2);...
     randn(100,2)-ones(100,2)];

[idx,ctrs] = KMeansCustom(X,2);
%[idx,ctrs] = kmeans(X,2);

plot(X(idx==1,1),X(idx==1,2),'r.','MarkerSize',12)
hold on
plot(X(idx==2,1),X(idx==2,2),'b.','MarkerSize',12)
plot(ctrs(:,1),ctrs(:,2),'kx',...
     'MarkerSize',12,'LineWidth',2)
legend('Cluster 1','Cluster 2','Centroids',...
       'Location','NW')

function [Idx,C]=KMeansCustom(X,k)
%KMeansCustom partitions the points in the n-by-d data matrix X into k clusters.
%[Idx,C]= KMeansCustom(X,k) returns 
%n-by-1 vector IDX containing the cluster indices of each point and 
%k-by-d matrix C containing the k cluster centroid locations.
%For n sample points with d dimensions in each point, X has n rows and d columns.
%File name: KMeanCustom.m
%Author: Yan Naing Aye
%Website: http://cool-emerald.blogspot.sg/


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%Define maximum number of iterations
MaxIter=500;
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
[n,d]=size(X);
k=round(k);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%step1 :arbitrarily choose k samples as the initial cluster centers
p=randperm(n);
Mu=X(p(1:k),:);
D=zeros(k,d);
for t=1:MaxIter
 %step2:distribute the samples X  to the clusters 
 for j=1:k
        for i=1:n
            D(j,i)=ChiDist(X(i,:),Mu(j,:));%Use custom distance
        end
 end
 [ValMin,IndexMin]=min(D);
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %step 3: update the cluster centers
    OldMu=Mu;
 for i=1:k
        Mu(i,:)=mean(X(IndexMin==i,:));
 end
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 %step4 :check convergence
 if sum(sum(abs(OldMu-Mu))) == 0 %< 1e-9
        break
 end
end
Idx=IndexMin';
C=Mu;

function d=ChiDist(v1,v2)
    dv=(v1-v2).^2;
    sv=abs(v1)+abs(v2);
    %------------------------------------------------------
    %eliminate zero denominator
    sv(sv==0)=1e-9;
    %------------------------------------------------------
    d=sum(dv./sv)./2;    
end

Amplitude spectrum of a signal using Fourier transform

signal တစ်ခုရဲ့ amplitude spectrum ကို Fourier transform သုံးပြီး ရှာတဲ့ MATLAB ဖန်ရှင်လေး တစ်ခု ရေးကြည့်ထားပါတယ်။ အဲဒီ ဖန်ရှင်ကို နမူနာ သုံးတဲ့ ပုံစံ ရယ်၊ ဖန်ရှင် ရေးထားတဲ့ ကုဒ်တွေ ရယ်ကို အောက်မှာ ဖော်ပြထားပါတယ်။ MATLAB မှာ ပါတဲ့ ဖန်ရှင် fft ကို သုံးတဲ့ ဟာ ကို လည်း နောက်ထပ် နမူနာ တစ်ခု ပြထားပါတယ်။ ဒီဟာလေးတွေက amplitude spectrum တို့၊ power spectrum တို့ ရှာချင်တဲ့ သူတွေ အတွက် အသုံးဝင်မယ်လို့ မျှော်လင့်ပါတယ်။
%Example MATLAB code to test function FX
Fs=100;
t=(0:1/Fs:1-1/Fs)';
x=2*cos(2*pi*5*t)+sin(2*pi*10*t);
[f a]=FX(x,Fs);
plot(f,a);

function [f a]=FX(x,fs)
%Calculates amplitude spectrum of a signal x using Fourier transform
%[f a]=FX(x,fs)
%Input: x=signal, fs = sampling rate
%Output: f = frequency axis, a = amplitude spectrum
%File name: FX.m
%Author: Yan Naing Aye
%Website: http://cool-emerald.blogspot.sg/

dT = 1/fs; 
N=length(x);
dF=1/(N*dT);
NF=fs/2;%Nyquist Freq
%You can always limit freq range for faster performance
%NF=20;
t=(0:dT:(N-1)*dT)';
f=(0:dF:NF)';
a=f;%initialize a
a(1)=mean(x);
for i=2 : length(a)
    b=(2*mean(x.*cos(2*pi*dF*(i-1)*t)));
    c=(2*mean(x.*sin(2*pi*dF*(i-1)*t)));
    a(i)=sqrt(b^2+c^2);
end

%MATLAB program to calculates amplitude spectrum of a signal x using fft
%Author: Yan Naing Aye
%Website: http://cool-emerald.blogspot.sg/

Fs=100;
t=(0:1/Fs:1-1/Fs)';
x=2*cos(2*pi*5*t)+sin(2*pi*10*t);
L=length(x);

A=2*abs(fft(x)/L);
A=A(1:Fs/2+1);
f = Fs/2*linspace(0,1,Fs/2+1);
plot(f,A);

Sunday, January 13, 2013

Changing sampling rate using quadratic regression

signal တစ်ခုရဲ့ sampling rate ကို 333Hz ကနေ 5000Hz ကို ပြောင်းဖို့ အတွက် လုပ်ကြည့်ထားပါတယ်။ ပိုမို ချောမွေ့တဲ့ ရလာဒ် ရချင်တာမို့ ပုံမှန် zero order hold (ZOH) ကို သုံးမယ့်အစား second order hold ကို သုံးကြည့်ထားတာပါ။ ဒီမှာ sampling rate ကို တင်ဖို့လုပ်ထားပေမယ့်၊ ဒီနည်းကို down sampling လုပ်ဖို့လည်း သုံးလို့ရပါတယ်။ အခြား ဖြစ်နိုင်ချေတွေကတော့ noise ကို phase delay မရှိပဲ filter လုပ်တဲ့ဟာမျိုးတွေ အတွက်လည်း သုံးလို့ ရနိုင်ပါတယ်။ real-time application တွေအတွက်ပေါ့။
Approach 1: Quadratic regression
Quadratic ဖန်ရှင်တစ်ခုကို အောက်ပါအတိုင်း သတ်မှတ်နိုင်ပါတယ်။

$$f=w_0+w_1 x + w_2 x^2$$

အနည်းဆုံး ဖြစ်အောင် လုပ်မယ့် cost function ကို အောက်ကလို သတ်မှတ်မှာပါ။

$$J(w)=\frac{1}{2}\sum_{i=1}^{n}(y_i-f_i)^2$$
$$J(w)=\frac{1}{2}\sum_{i=1}^{n}(y_i-w_0+w_1 x_i + w_2 x_i^2)^2$$

ဒါဆို Optimal weights တွေကို differentiate လုပ်ပြီးသုည ညီလိုက်ပြီး ရှာနိုင်ပါတယ်။

$$\frac{\partial J(w)}{\partial w_0}=0$$
$$-\sum_{i=1}^{n}(y_i-w_0+w_1 x_i + w_2 x_i^2)=0$$
$$w_0\sum_{i=1}^{n}1+w_1\sum_{i=1}^{n}x_i+w_2\sum_{i=1}^{n}x_i^2=\sum_{i=1}^{n}y_i$$

w1 နဲ့ w2 ကိုလည်း အဲဒီလိုပဲ ရှာလိုက်မယ် ဆိုရင် အောက်အတိုင်း ထပ်ရလာပါမယ်။

$$w_0\sum_{i=1}^{n}x_i+w_1\sum_{i=1}^{n}x_i^2+w_2\sum_{i=1}^{n}x_i^3=\sum_{i=1}^{n}y_i x_i$$
$$w_0\sum_{i=1}^{n}x_i^2+w_1\sum_{i=1}^{n}x_i^3+w_2\sum_{i=1}^{n}x_i^4=\sum_{i=1}^{n}y_i x_i^2$$

အဲဒီ equation သုံးခုကို မေ့ထရစ် ပုံစံ နဲ့ အောက်ပါအတိုင်း ရေးလို့ရပါတယ်။

$$ \begin{bmatrix} \sum_{i=1}^{n}1 & \sum_{i=1}^{n}x_i & \sum_{i=1}^{n}x_i^2 \\ \sum_{i=1}^{n}x_i & \sum_{i=1}^{n}x_i^2 & \sum_{i=1}^{n}x_i^3 \\ \sum_{i=1}^{n}x_i^2 & \sum_{i=1}^{n}x_i^3 & \sum_{i=1}^{n}x_i^4 \end{bmatrix} \begin{bmatrix} w_0 \\ w_1 \\ w_2 \end{bmatrix} = \begin{bmatrix} \sum_{i=1}^{n}y_i \\ \sum_{i=1}^{n}y_i x_i \\ \sum_{i=1}^{n}y_i x_i^2 \end{bmatrix} $$
$$\mathbf{A}\mathbf{W}=\mathbf{B}$$
$$\mathbf{W}=\mathbf{A}^{-1}\mathbf{B}$$

Approach 2: Three equations
တကယ်တော့ ဒီကိစ္စမှာ နောက်ဆုံး အမှတ် ၃ ခုကိုပဲ သုံးလိုက်ရင်ရတဲ့ အတွက်၊ ညီမျှခြင်း သုံးကြောင်း ကို အောက်က အတိုင်း တစ်ခါတည်း ချရေးလို့လည်း ရပါတယ်။


$$y_1=w_0+w_1 x_1 + w_2 x_1^2$$
$$y_2=w_0+w_1 x_2 + w_2 x_2^2$$
$$y_3=w_0+w_1 x_3 + w_2 x_3^2$$
$$ \begin{bmatrix} 1 & x_1 & x_1^2 \\ 1 & x_2 & x_2^2 \\ 1 & x_3 & x_3^2 \end{bmatrix} \begin{bmatrix} w_0 \\ w_1 \\ w_2 \end{bmatrix} = \begin{bmatrix} y_1 \\ y_2 \\ y_3 \end{bmatrix} $$
$$\mathbf{A}\mathbf{W}=\mathbf{B}$$
$$\mathbf{W}=\mathbf{A}^{-1}\mathbf{B}$$

Approach 3: Two equations အကယ်၍ x1=-1, x2=0, နဲ့ x3=1 လို့ သတ်မှတ်လို့ ရတယ်ဆိုရင် y2 က w0 နဲ့ ညီသွားပါမယ်။ နောက်ကျန်တဲ့ အမှတ် ၂ ခုကနေ ညီမျှခြင်း နှစ်ကြောင်းပဲ ရှင်းဖို့ လိုပါတော့တယ်။

$$y_1=y_2-w_1+ w_2$$
$$y_3=y_2+w_1+ w_2$$
$$ \begin{bmatrix} -1 & 1 \\ 1 & 1 \end{bmatrix} \begin{bmatrix} w_1 \\ w_2 \end{bmatrix} = \begin{bmatrix} y_1-y_2 \\ y_3-y2 \end{bmatrix} $$
$$ \begin{bmatrix} w_1 \\ w_2 \end{bmatrix} = \begin{bmatrix} -0.5 & 0.5 \\ 0.5 & 0.5 \end{bmatrix} \begin{bmatrix} y_1-y_2 \\ y_3-y2 \end{bmatrix} $$

နောက် အောက်ကအတိုင်းရလာပါမယ်။

$$w_0=y_2$$
$$w_1=-0.5(y_1-y_2)+0.5(y_3-y2)$$
$$w_2=0.5(y_1-y_2)+0.5(y_3-y2)$$

အထက်ကနည်းတွေကို MatLab နဲ့စမ်းကြည့်ထားတာကို အောက်က ကုဒ်တွေမှာ တွေ့နိုင်ပါတယ်။
%-------------------------------------------------------------------------
clc;
close all;
clear all;
%-------------------------------------------------------------------------
% y= w0 + w1*x + w2* x^2;
%-------------------------------------------------------------------------
%Got x and y
x=[-1 0 1]';
Wo=[4 3 2]';
y=Wo(1)+Wo(2)*x+Wo(3).*x.*x;

%-------------------------------------------------------------------------
%Approach 1
%Polynomial regression of order 2
%For n=3
S1=3;
Sx=sum(x);
Sx2=sum(x.*x);
Sx3=sum(x.*x.*x);
Sx4=sum(x.*x.*x.*x);
Sy=sum(y);
Syx=sum(y.*x);
Syx2=sum(y.*x.*x);

P=[S1 Sx Sx2; Sx Sx2 Sx3; Sx2 Sx3 Sx4];
B=[Sy Syx Syx2]';
%P1=P^(-1);
W1=P\B

%-------------------------------------------------------------------------
%Approach 2
%Linear equations
A=[1 x(1) x(1)*x(1);1 x(2) x(2)*x(2); 1 x(3) x(3)*x(3)];
W2=A\y
%-------------------------------------------------------------------------
%Approach 3
%Only 2 linear equations
w0=y(2);
w1=-0.5*( y(1)- y(2))+0.5*( y(3)- y(2));
w2=0.5*( y(1)- y(2))+0.5*(y(3)- y(2));
W3=[w0 w1 w2]'
%-------------------------------------------------------------------------
အောက်ကပုံမှာ ဒီနည်းကို သုံးလို့ရတဲ့ ရလဒ် (အပြာ) နဲ့ ပုံမှန် zero order hold သုံးရင် ရမယ့် ရလဒ် (အနက်) တို့ကို ယှဉ်ပြထားပါတယ်။ ဒီနည်းက ပိုပြီး ညက်ညော ချောမွေ့တဲ့ ရလဒ်ကို ရပေမယ့် one sample delay ရှိသွားတာကိုတော့ သတိထားဖို့ လိုပါတယ်။
ဒီနည်းလမ်းကို LabVIEW မှာ C code သုံးပြီး လုပ်ထားတာကို အောက်ကပုံမှာ တွေ့နိုင်ပါတယ်။
ပထမ နှစ်ခုမှာ 3x3 matrix ကို inverse ရှာဖို့ လိုတဲ့အတွက် inverse ရှာတဲ့ C program လေးတစ်ခုကို ရေးပြီး စမ်းကြည့်ထားပါတယ်။
#include
#include
main()
{
    float M[3][3]={{3,0,2},{0,2,0},{2,0,2}}; //initialize a 3x3 matrix
    float N[3][3]={{0,0,0},{0,0,0},{0,0,0}}; //allocate for inverse
    int i,j;
    float d;
    //-------------------------------------------------------------------------
    N[0][0]=(M[1][1]*M[2][2]-M[2][1]*M[1][2]);
    N[1][0]=-(M[1][0]*M[2][2]-M[2][0]*M[1][2]);
    N[2][0]=(M[1][0]*M[2][1]-M[1][1]*M[2][0]);
    d=M[0][0]*N[0][0]+M[0][1]*N[1][0]+M[0][2]*N[2][0];
    N[0][0]/=d;
    N[1][0]/=d;
    N[2][0]/=d;
    N[0][1]=-(M[0][1]*M[2][2]-M[0][2]*M[2][1])/d;
    N[1][1]=(M[0][0]*M[2][2]-M[0][2]*M[2][0])/d;
    N[2][1]=-(M[0][0]*M[2][1]-M[0][1]*M[2][0])/d;
    N[0][2]=(M[0][1]*M[1][2]-M[0][2]*M[1][1])/d;
    N[1][2]=-(M[0][0]*M[1][2]-M[0][2]*M[1][0])/d;
    N[2][2]=(M[0][0]*M[1][1]-M[0][1]*M[1][0])/d;
    //-------------------------------------------------------------------------
    //print 3x3 matrix
    for(i=0;i<3;i++)
    {
        for(j=0;j<3;j++) printf("%3.4f ",N[i][j]);
        printf("\n");
    }
    getch();
    return 0;
}

Wednesday, March 7, 2012

Skeleton of Image Region

ပုံရိပ် တစ်ခုရဲ့ တည်ဆောက်ပုံ ပုံသဏ္ဌာန် ကို မျဉ်းကြောင်းများနဲ့ တုတ်ချောင်းပုံ လုပ်ပြီး ကိုယ်စားပြု ဖော်ပြနိုင်ပါတယ်။ အဲဒီလို ဖော်ပြဖို့အတွက် ပုံသဏ္ဌာန် တစ်ခုကို တဖြည်းဖြည်း ပိန်ပါးသွားအောင် လုပ်နည်း တစ်ခုခု ကို သုံးလို့ရပါတယ်။ ရလာတဲ့ မျဉ်းကြောင်းများနဲ့ တုတ်ချောင်းပုံ ကို အဲဒီ ပုံရဲ့ အရိုး (skeleton) လို့ ခေါ်ပါမယ်။ ဒီနည်းဟာ စာလုံးများကို စက်က သိရှိနားလည် မှတ်မိ အောင် လုပ်တဲ့ နေရာ (optical character recognition) တွေမှာ ပဏာမ အဆင့် အနေနဲ့ အသုံးကျကောင်း ကျနိုင်ပါတယ်။ အောက်ကပုံတွေမှာ နမူနာ မူရင်းပုံနဲ့ သူ့ရဲ့ အရိုးကို ဖော်ပြထားပါတယ်.
ပုံရိပ်တစ်ခု ရဲ့ အရိုးကို နည်းအမျိုးမျိုးနဲ့ ရယူနိုင်ပြီး အဲဒီ နည်းတွေထဲက လူသိများတဲ့ နည်းနှစ်နည်းက အလယ်ဝင်ရိုးပြောင်းနည်း Medial Axis Transformation (MAT) နဲ့ နှစ်ဆင့်ပါးနည်း Two Step Thinning တို့ပါ။ MAT မှာ ပုံသဏ္ဌာန် ထဲမှာ ရှိတဲ့ အစက် တစ်စက် ချင်းစီ အတွက် သူတို့ ရဲ့ အနီးဆုံး အနားသတ် ကို လိုက်ရှာပါတယ်။ အဲဒီလို အကွာအဝေးတူ အနီးဆုံး အနားသတ် တစ်ခုမက ရှိတဲ့ အစက်ကို အရိုး လို့သတ်မှတ်ပါတယ်။ MAT ကနားလည်ဖို့ လွယ်ပေမယ့် သူ့ကိုရဖို့ တွက်ချက်မှုတွေ အများကြီး လိုပါတယ်။ သူ့ကို တွက်ဖို့ အကွာအဝေးပုံစံ ပြောင်းခြင်း (distance transform) ကို အရင် လုပ်ပါတယ်။ အကွာအဝေးပုံစံ ပြောင်းတယ်ဆိုတာ ပုံသဏ္ဌာန် ထဲမှာ ရှိတဲ့ အစက် တစ်စက် ချင်းစီ ကို အနီးဆုံး အနားသတ်အထိ အကွာအဝေးနဲ့ အစားထိုးတာပါ။ ရလာတဲ့ ပုံမှာ အနားသတ်နဲ့ နီးတဲ့ အစက်က အကွာအဝေး တန်ဖိုးနည်းတော့ အလင်းအားပျော့ ပြီး၊ အနားသတ်နဲ့ ဝေးတဲ့ အစက်က အကွာအဝေးတန်ဖိုးကြီးတော့ ပိုလင်းပါမယ်။ နောက် အစက်တစ်စက် ခြင်းစီကို ဘေးတိုက် ဒါမှမဟုတ် ဒေါင်လိုက် ကပ်ရပ် အစက်တွေနဲ့ ယှဉ်ကြည့်ပြီး အလယ်မှာ အမြင့်ဆုံး ဖြစ်နေတဲ့ အစက်တွေကို အရိုးလို့ သတ်မှတ်ပါမယ်။ နမူနာ MATLAB ကုဒ် ကို ဒီမှာ (MATeg.m) ကြည့်နိုင်ပါတယ်။ မူရင်း ပုံသဏ္ဌာန်ရယ်၊ အကွာအဝေးပုံစံ ရယ်၊ ရလာတဲ့ အရိုးရယ် ကို အောက်က ပုံတွေမှာ ကြည့်နိုင်ပါတယ်။


နှစ်ဆင့်ပါးနည်း ကတော့ MAT နဲ့ယှဉ်ရင် ပိုမြန်၊ ပိုထိရောက်ပါတယ်။ နှစ်ဆင့်ပါးနည်း က ပုံသဏ္ဌာန် တစ်ခုရဲ့ အနားတွေကို ထပ်တလဲလဲ ဖျက်သွားတာပါ။ အဲဒီလို ဖျက်တဲ့ အခါမှာ အဆုံးမှတ်တွေကို မဖျက်ပါဘူး။ တနေရာနဲ့ တနေရာ ဆက်စပ်နေတဲ့ အမှတ်တွေကို မဖျက်ပါဘူး။ ပုံသဏ္ဌာန် ထဲမှာ ရှိတဲ့ အစက် တွေကို တန်ဖိုး တစ်ရှိတယ်လို့ မှတ်ယူ မှာ ဖြစ်ပြီး နောက်ခံ အစက်တွေကို တော့ တန်ဖိုး သုည ရှိတယ် လို့ မှတ်ယူပါမယ်။ ဒီနည်းမှာ အဆင့် နှစ်ဆင့် ကို ပုံပေါ်မှာ အထပ်ထပ် အဖန်ဖန် နောက်ဆုံး မပြောင်းလဲတဲ့ အရိုး ရတဲ့အထိ သုံးသွားမှာပါ။
အပေါ်ပုံမှာ အလယ် အစက်ရဲ့ ကပ်ရပ် အစက်တွေကို အခေါ်အဝေါ်သတ်မှတ်ပုံကို ပြထားပါတယ်။ ပထမ အဆင့်မှာ အစက် p1 ကို အောက်က အချက်လေးချက်နဲ့ ကိုက်ညီရင် ဖျက်ပစ် ပါမယ်။ (a) 2 ≤ N(p1) ≤ 6 (b) T(p1) = 1 (c) p2.p4.p6 = 0 (d) p4.p6.p8 = 0 အဲဒီမှာ N(p1) ဆိုတာက p1 နဲ့ ကပ်ရပ် အစက်တွေထဲက သုညမဟုတ်တဲ့ အစက် အရေအတွက်ဖြစ်ပြီး၊ T(p1) ဆိုတာက p2, p3, ... , p8, p9, p2 ဆိုတဲ့ အစီအစဉ်အတိုင်း ကြည့်သွားရင် ၀ ကနေ ၁ ကို ပြောင်းသွားတဲ့ အရေ အတွက်ပါ။ ဒုတိယ အဆင့်မှာ (a) နဲ့ (b) ကအတူတူပါပဲ။ ဒါပေမယ့် (c) နဲ့ (d) ကတော့ အောက်မှာ ပြထားတဲ့ အတိုင်း ပြောင်းသွားပါတယ်။ (c') p2.p4.p8= 0 (d') p2.p6.p8= 0 ပထမ အဆင့် ကို ပုံသဏ္ဌာန်တစ်ခုရဲ့ အနားသတ်ပေါ်မှာရှိတဲ့ အစက်တိုင်းအတွက် စဉ်းစားပါမယ်။ အချက် (a) ကနေ (d) ထဲက တစ်ချက်ချက် မကိုက်တာနဲ့ အဲဒီ အစက်ကို မဖျက်တော့ ပါဘူး။ အချက်အားလုံး ကိုက်ညီရင် တော့ ဖျက်ဖို့ အတွက် မှတ်ထားလိုက် ပါမယ်။ ဒါပေမယ့် အဲဒီ အစက် ကို အနားသတ် ပေါ်မှာရှိတဲ့ အစက် အားလုံးကို စဉ်းစားလို့ မပြီးမချင်း တကယ် မဖျက်သေးပါဘူး။ အဲဒီလို နောက်ကျမှ ဖျက်တဲ့ အတွက် တစ်ခြား အစက် တွေကို စဉ်းစား နေတဲ့ အချိန်မှာ ပုံသဏ္ဌာန် ပြောင်းသွားတာကို ကာကွယ်နိုင်ပါတယ်။ ပထမ အဆင့် ကို အနားသတ်ပေါ်မှာရှိတဲ့ အစက် အားလုံးကို စဉ်းစာပြီးပြီဆိုတာနဲ့ ဖျက်ဖို့မှတ်ထားတဲ့ အစက် အားလုံးကို ဖျက်လိုက်ပါမယ်။ (အစက်ရဲ့ တန်ဖိုးကို သုည ပြောင်းလိုက်တာပါ။) ရလာတဲ့ ရလဒ် ပေါ်မှာ ဒုတိယ အဆင့် ကိုလဲ ပထမအဆင့် အတိုင်း ထပ်သုံးပါမယ်။ ဒီ အဆင့်နှစ်ဆင့်ကို အကြိမ်ကြိမ် အဖန်ဖန် ပြန်သုံးမှာ ဖြစ်ပြီး အကြိမ်တစ်ကြိမ်တိုင်းမှာ အောက်က လုပ်ငန်းလေးခုကို လုပ်ပါတယ်။ (၁) ပထမ အဆင့်ကို သုံးပြီး ဖျက်ရမယ့် အစက်တွေကို မှတ်ပါတယ်။ (၂) မှတ်ထားတဲ့ အစက်တွေကို ဖျက်ပါတယ်။ (၃) ဒုတိယ အဆင့်ကို သုံးပြီး ဖျက်ရမယ့် အစက်တွေကို မှတ်ပါတယ်။ (၄) မှတ်ထားတဲ့ အစက်တွေကို ဖျက်ပါတယ်။ ဒီအဆင့်တွေကို သုံးပြီး ပါးပါးသွားရင်း နောက်ဆုံး ဖျက်စရာ အစက် မကျန်တော့ဘူးဆိုရင် ရပ်လိုက်ပါမယ်။ ရလာတဲ့ ပုံက အရိုးဖြစ်ပါတယ်။ အချက် (c) p2.p4.p6 = 0 နဲ့ (d) p4.p6.p8 = 0 ကို တစ်ခါထဲ ပေါင်းပြီး (p4 = 0 or p6= 0) or (p2=0 and p8=0) လို့ တန်းစစ်လို့လဲရပါတယ်။ အဲဒီလိုပဲ (c') နဲ့ (d') ကိုလဲ (p2=0 or p8=0) or (p4=0 and p6=0) လို့ ပေါင်းစစ်လို့ ရပါတယ်။ Two Step Thinning အတွက်နမူနာ MATLAB ကုဒ်ကို ဒီမှာ (TSTeg.m) တွေ့နိုင်ပါတယ်။
ရှေ့မှာ ဖော်ပြခဲ့တဲ့ ကုဒ်တွေက နည်းတွေကိုနားလည်ဖို့ ရယ်၊ တစ်ခြား ပရိုဂရမ် ဘာသာတွေနဲ့ ပြန်ရေးဖို့ရယ် အတွက်တော့ အထောက် အကူ ဖြစ်မယ်ထင်ပါတယ်။ တကယ်တော့ MATLAB မှာ bwmorph ဆိုတဲ့ ဖန်ရှင်ကို သုံးလိုက်တာနဲ့ အရိုးကို တန်းရနိုင်ပါတယ်။ sk=bwmorph(bwImg,'skel',Inf); အဲဒီလိုခိုင်းလိုက်ရင် ထွက်လာတဲ့ ရလဒ် ကို အောက်မှာ ပြထားပါတယ်။
Reference: Rafael C. Gonzalez, Richard E. Woods, Steven L. Eddins, "Digital Image Processing Using MATLAB", Second Edition, Mc Graw Hill (Asia), 2011.

Friday, December 30, 2011

Testing fsolve and anonymous function

တစ်ခါက coefficient တွေ ပြောင်းလဲ နေတဲ့ equation တွေကို ဖြေရှင်းဖို့ လို လာပါတယ်။ ဒါနဲ့ MatLab ဖန်ရှင်တစ်ခု ဖြစ်တဲ့ fsolve ရယ်၊ function handle နဲ့ anonymous function တွေကို သုံးပြီး စမ်းကြည့်ထားတာပါ။
s=[3 7 11];
d=[1 3 5];
%ans= (2,1), (5,2), (8,3)
for i=1:3
x0 = [-5; -5]; % Make a starting guess at the solution
myfun =@(x) [x(1) + x(2) - s(i);
x(1) - x(2) - d(i)];
[x,fval] = fsolve(myfun,x0)  % Call 
end