2018年4月23日 星期一

How to add new patterns to tesseract (create new traineddata)


Environment
jTessBoxEditorFX-2.0-Beta / tesseract 4.0.0-alpha.20180109
download url
https://jaist.dl.sourceforge.net/project/vietocr/jTessBoxEditor/jTessBoxEditorFX-2.0-Beta.zip


The zip file already includes tesseract 4.0, it doesn't download.

Process steps
1. Build the private patterns with paint. The file name must be followed the example, other wise the process might cannot work well. The file name is temp.font.exp0.tif
2.  Using tesseract to build the box file as following command line.
          tesseract temp.font.exp0.tif temp.font.exp0 batch.nochop makebox
3.  Using jTessBoxEditor to adjust the .box file to make sure the mapping between letter and images are correct.
4. build font_properites.txt file for bat file to use.
5. Execute the bat file to build the  temp.traineddata for emug to use.

The following is the content of the bat file.
============START OF BAT===================
echo Run Tesseract for Training..
..\tesseract.exe temp.font.exp0.tif temp.font.exp0 nobatch box.train

echo Compute the Character Set..
..\unicharset_extractor.exe temp.font.exp0.box
..\shapeclustering.exe -F font_properties.txt -U unicharset temp.font.exp0.tr
..\mftraining.exe -F font_properties.txt -U unicharset temp.font.exp0.tr

echo Clustering..
..\cntraining.exe temp.font.exp0.tr

echo Rename Files..
rename normproto temp.normproto
rename inttemp temp.inttemp
rename pffmtable temp.pffmtable
rename shapetable temp.shapetable
rename unicharset temp.unicharset

..\combine_tessdata.exe temp.
==========END OF BAT======================

2018年4月22日 星期日

如何加入自己的模版 How to add the patterns to Tesseract OCR

環境
jTessBoxEditorFX-2.0-Beta / tesseract 4.0.0-alpha.20180109

下載連結
https://jaist.dl.sourceforge.net/project/vietocr/jTessBoxEditor/jTessBoxEditorFX-2.0-Beta.zip

連結下載的壓縮檔已內含 tesseract 的執行環境,不須另外下載。

操作步驟
1. 建立模版圖檔,檔名的格式似乎有特別的結構需要遵從。檔名取名為temp.font.exp0.tif 如果沒有把握能正確完成,請使用這個檔名。
2. 使用tesseract 將模版圖檔處理後產生 temp.font.exp0.box 檔。產生.box  檔案的命令為
 
          tesseract temp.font.exp0.tif temp.font.exp0 batch.nochop makebox

3. 使用jTessBoxEditor 調整 .box 檔案 以確保模版與字元的對應是正確的。
4. 建立font_properties.txt 檔案以供後需.bat 檔案使用
5. 執行以下.bat 檔案中的命令,以產生最後emgu可以使用的 temp.traineddata.

以下是.bat file 的內容
The following is the content of the bat file.
============START OF BAT===================
echo Run Tesseract for Training..
..\tesseract.exe temp.font.exp0.tif temp.font.exp0 nobatch box.train

echo Compute the Character Set..
..\unicharset_extractor.exe temp.font.exp0.box
..\shapeclustering.exe -F font_properties.txt -U unicharset temp.font.exp0.tr
..\mftraining.exe -F font_properties.txt -U unicharset temp.font.exp0.tr

echo Clustering..
..\cntraining.exe temp.font.exp0.tr

echo Rename Files..
rename normproto temp.normproto
rename inttemp temp.inttemp
rename pffmtable temp.pffmtable
rename shapetable temp.shapetable
rename unicharset temp.unicharset

..\combine_tessdata.exe temp.
==========END OF BAT======================



2018年3月30日 星期五

Arduino+L298N+high toque stepper motor speed control mechanism 步進馬達控速 (240RPM to 45RPM)

    控制電路可以讓步進馬達不使用減速齒輪組的條件下,在二個不同的轉速之間切換(240~180RPM與90~30RPM之間)進行變速以避免L298N過熱與降低轉速時的震動,控制電路使用可變電阻與控制duty cycle的方式進行調速。控制電路使用一個Arduino UNO,一個L298N 馬達控制模組,一個電驛模組搭配組成開迴路的馬達轉速控制。使用12DCV與5DCV做為步進馬達的供電電壓。步進馬達的型號是PKP266D28A 東方馬達公司製造。這個變速方式的限制是,馬達軸上不能有反轉矩的力量。否則會因為馬達未激磁時沒有力量可以抵消反轉矩,這樣會造成反轉與劇烈震動的情況。另外這個程式的功能很單純只進行馬達的轉動控制。如果要處理器同時要處理其他的工作例如通訊等其他較為耗時的運算時,用來控制duty cycle 的機制也要進行改動與調整。熟悉Arduino 與步進馬達控制的人可以直接參考以下的電路與程式碼。

     Using relay to switch the motor supply voltage can be more easy to switch RPM in two ranges. using this method can avoid the L298N over heat and reduce the shaking when motor was under the low speed. The RPM of the stepper motor can be fine turn with a variable resistor and a ADC input. The control circuit is assemble by an Arduino UNO, a L298N motor driver, a single relay module, and a +5VDC/+12VDC dual output switching power.The part number of stepper motor is PKP266D28A. The following code is used to implement low RPM setting.

 在調速的部份與Arduino IDE 內建的example 不同的地方在於加入了Delay以及使用關閉電源的方式來降低馬達的平均驅動電流,以避免L298N過熱的狀況發生。程式中設定Delay 7ms 是為了讓馬達在90RPM的轉速設定下能夠完成2個steps的驅動,約需時6.6ms。

要降低馬達的轉速只需要增加iDelayTime的數值。馬達需要轉動2steps的時間增加等於馬達的轉速降低。

依程式的設定最低的轉速可以降至 100cycle * 57 ms = 5.7sec/rotate 約等於 60sec/5.7sec=10.52 rpm。

// set the motor speed:
digitalWrite(3,LOW);          // turn off the relay to supply +5VDC to stepper motor. myStepper.setSpeed(90);  // step 1/100 of a revolution:
myStepper.step(-stepsPerRevolution/100 );
// tow steps will take 1sec/(90rpm/60second*200steps) is about 3.3 ms per step. 
delay(7);         // Time windows for driving the motor for two steps 
// turn off the stepper motor supply power 
digitalWrite(8,LOW); 
digitalWrite(9,LOW); 
digitalWrite(10,LOW); 
digitalWrite(11,LOW);
int iDelaytime = map(iADCRead, 0, 1000, 1, 50);
delay(iDelaytime); // turn off duty time

2018年2月26日 星期一

c# retrieve datetime field from sqlite when you have an error "String was not recognized as a valid DateTime."

"String was not recognized as a valid DateTime." This error is caused by the data string which you save in the database with wrong formate. for solving this error, you just need to adjust you data string to follow the formate as "yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd HH:MM:SS.sssss" if you have ms information need to save. 發生錯誤 "String was not recognized as a valid DateTime." 是因為在sqlite 資料庫中的時間資料字串格式無法讓C#的物件解讀造成的。所以只要將存入的資料,修改成符合C#需要的時間格式即可順利運作。符合的資料格式為"yyyy-mm-dd HH:MM:SS" or "yyyy-mm-dd HH:MM:SS.sssss" 如果你有ms的時間資訊需要填入。

2016年6月29日 星期三

為一個精確的ADC提供一個簡易可靠的參考電壓 (A simple and reliable reference voltage for an accurate ADC) TL431



因為使用Arduion 做為電池容量測試的工具並以電腦做為長期資料收集的後端。因為Arduino 吃電腦USB的電,所以Arduino無法使用內部的參考電位做為ADC的參考電壓。必須要額外使用一個穩定和足夠精準的參考電壓,來做為ADC 的校正。這樣才能保證ADC計算出來的電池電壓值的精確度在一定的範圍內。便宜方便的做法是使用一顆TL431,它的2.5V的電壓輸出,做為ADC自我校正的參考電位。其電路如下圖所示:

這個參考電壓電路只要一顆TL431與一顆電阻的組成,就可以得到一個穩定的2.5V的參考電壓。input 接Arduino的VCC, Vka就接到ADC的輸入做為校正電壓。


The circuit on Figure 1 is used to get a reliable and stable reference voltage. Usually the ADC will not be accurate when Arduino connected to PC via USB. If we want a accurate ADC to voltage mapping, we will need a reference voltage to calibrate it. The figure 1 is a sample way to solve this question. The VKA will be a stable  2.5 voltage. MCU can used to calibrate the mapping relation.




2016年4月24日 星期日

按鈕或開關彈跳的問題 (Button Debounce)


今天找到一個更好的解決方法,網址如下:

https://electrosome.com/switch-debouncing/


I think the best solution is "Hardware" solution, if there is no limitation of dimension.  I use a sample RC circuit (shows as below) which can be found on Internet easily. The resister and capacitor values which I used are 250K ohm and 0.1 uF. The basic rule to choose the value of R and C are, small C can be discharged quickly when switch closed, and high value of R will charge slowly. I think the limitation of this debounce circuit is that this circuit can not handle the high frequency switch action. Regarding the values of RC, it will take about 0.125 second to charge capacitor from 0 V to 5 V. The RC value can be calculated in fact. 5 * R * C is time of C charge to 5V, and discharge time will be 5 * C (assumed the resistor in switch is 1 ohm). and the rule is discharged time is sorter than bounce cycle time, and charge time much longer than bounce cycle time. Regarding measurement, the bounce cycle time of the switch is about 50 us.

如果沒有硬體空間限制的問題的話,我想採用硬體的對策是最好的消除彈跳的方法。我這次使用的數值是250K歐姆的電阻,以及0.1uF的電容器。電路如下圖所示。我想這個電路的限制是,無法使用在高速切換的開關電路上,因為充電的時間比較長。依照電容充放電的特性,與所選的數值。在開關打開後約須0.125秒的時間,電容器才能充電到5伏特。電阻電容值事實上可以通過計算決定。5 *R*C為充電時間,5*C為放電的時間(假設開關電路阻抗為1歐姆)。充電的時間必須要比跳跳訊號的週期長,而放電的時間則是要比彈跳的週期短。依據視波器的量測,彈跳週期約為50 us。






Bounce signal when R C values are not good enough.



2015年7月7日 星期二

Emgu 把二個影像合成一個影像

第一步 首先建立一個夠大的 image 底圖. 這行程式碼是依照OCR的ROI大小建立的。

 Image combine_image = new Image(new Size(roi_window.getWidth(), roi_window.getHeight())); 

第二步 然後在這個底圖上建立一個ROI的區域,這個目是要讓需要組合的畫面能放在正確的位置上。

 combine_image.ROI = new Rectangle(0+x_shift, 0, _processDigit_array[i].Width, _processDigit_array[i].Height); 


 第三步,將要組合的畫面放在底圖上
 _processDigit_array[i].CopyTo(combine_image); 

 第四步,移動ROI的位置,再將第二張畫面放在底圖上

 x_shift = x_shift + _processDigit_array[i].Width;


 第五步,將ROI的大小設為零,這個步驟等於是取消底圖上的ROI,
這檥才能讓底圖正常顯示在 imagebox 上。
 combine_image.ROI = new Rectangle(0, 0, 0, 0);


 程式碼片段

 Image< Gray, Byte> combine_image = new Image< Gray, byte>( new Size(roi_window.getWidth(), roi_window.getHeight()));
int x_shift = 0;
for ( int i = 0; i < _processDigit_array.Count; i++)
{
    combine_image.ROI = new Rectangle(0+x_shift, 0, _processDigit_array[i].Width, _processDigit_array[i].Height);
    _processDigit_array[i].CopyTo(combine_image);
    x_shift = x_shift + _processDigit_array[i].Width;
}
combine_image.ROI = new Rectangle(0, 0, 0, 0);

imageBox_after_threshold.Image = combine_image;