星期三, 5月 26, 2021

COVID-19 (新冠/武漢 肺炎) 各縣市官方捐款網頁 (滾動更新)


1.  台北市

台北市救助資源整合平台網址 https://rmic.gov.taipei/Web/RSADM00001

- 進入填單後, 市府將 e-mail 捐款者繳費單


2. 新北市

新北市好日子愛心大平台: https://goodday.ntpc.gov.tw/pwntpc/


2.1. 加入

-  進入 我要捐款  https://goodday.ntpc.gov.tw/pwntpc/memb/donateMoney , 以 "新冠肺炎" 查詢, 可進入 「新北市政府因應新冠肺炎防疫工作專案基金方案」
    










星期四, 11月 19, 2020

Python re 筆記 1-1: Regular Expression HOWTO/Simple Patterns

Regular Expression HOWTO  是 Python 官網推薦的 "正規表示法" 學習文件,在此翻譯和筆記心得,順其章節但不逐字翻。

Introduction 介紹正規表示式

正規表示式 Regular expression (REs, reges, reges patterns) 被用以在 string 中找 pattern。

(更務實的理解是用匹配詞 (pattern) 在文 (string) 中找出特定字。做為 python 使用者,在 import re 後,對 re 提供的各函式提供 pattern,也就是符合正規表示式文法的 regular expression。對 re 來說,pattern 字串編譯成 pattern object 後才有搜尋作用)


Simple Patterns 簡易匹配詞 

Matching Characters 

最直觀的匹配詞 pattern 就是想找的特定字。比如想找 test,匹配詞就是 test。
但有許多具有功能性的 metacharacters (匹配元),它們出現在 pattern 中具有其他意義。以下綠底為匹配元:
. ^ $ * + ? { } [ ] \ | ( )

方框 []:提供任一可匹配的[characters] ,和任何不可匹配的 [^characters] 
  • 方框內的任一字元都可找出
    • 比如 [abc] ,表示可找出 a 或 b 或 c 。
    • 連續性的字元集,比如 [abc] ,可用 '-' 表示連續性,表示為 [a-c] 。小寫英文字母常以 [a-z]  表示。
    • 匹配元在方框內也可以當成普通字元用。比如  [akm$] ,錢字號$是匹配元,作用為置後,但在方框內只是個普通可比對的字元。所以[akm$]可找出 'a''k', 'm',和 '$'
    • (私下覺得方框還原了匹配詞就是比對字的原始定義)
  • 在方框內首字元用 '^' 表示,則任何在方框內的字元都不可匹配,也就是 "所有不在方框內的字都符合" !!
    • 比如 [^5] ,5 以外的字元都可找出。
    • 注意當 '^' 不在方框首位,就當作普通字。比如[5^] 可找出 '5' 和 '^'
反斜線 是最重要的匹配元,有跳脫功能性帶入功能性的作用。

跳脫功能性之反斜線 \
  • Pattern內存在的匹配元有功能,無法視為比對內容。比如 [ 或 \ ,不可視為 "找左方框" 和 "找反斜線"。
  • 不過,將匹配元前配上反斜線\後,匹配元跳脫功能性回歸成一般字元,比方 \[ 和 \\ ,就視為 "找左方框"  和 "找反斜線"。
帶入功能性之反斜線 \:普通字元要怎麼有功能性呢?用久了,我們會期待數字可用某個字元表示,所有字母也用某字元表示,那這些普通字變成功能字,也是由反斜線帶入
  • \d:等義 [0-9],所有數字。
  • \D:等義 [^0-9],所有非數字。
  • \s:等義 [\t\n\r\f\v],所有空白字元。\t是水平跳格,\v是垂直跳格;\r是回車,\n是新行;\f換頁。
  • \S:等義 [^\t\n\r\f\v],所有非空白字元。
  • \w:等義 [a-zA-Z0-9_],所有字母數字元。
  • \W:等義 [^a-zA-Z0-9_],所有非字母數字元。
最懶點字元 .:可匹配任何非新行\n的字元。re 還提供 re.DOTALL 可匹配一切含新行\n的任何字元。

剩下的匹配元 * + ? { } | ( ) 將在後文說明

重複量詞

描述某字元某詞的重複次數。

米字號 *:0或多次

加字號 +:一次以上

問字號 ?:無或有(只出現一次)
  • 比如 home-?brew 可找出 'homebrew' 或 'home-brew'
大括號 {m,n}:指定重複次數
  • 出現 m~n 次:至少 m 次,最多 n 次。
    • 省略 m 次表示至少 0 次。
    • 省略 n 表示至多任意數量,所以有 {0,}{1,}{0,1} 等義 *,+ ,? 的用法
重複字元 * 有貪婪性,RE 會盡可能找出最多,之後的比對不合後,才減少重複量,返回前字元再比對。以 pattern  a[bcd]*b 找 string  'abcbd' 為例。


Matched

Explanation

1

a

狀態: string  'abcbd'; pattern  a[bcd]*b,工作pattern是 a. 

工作RE找到 a. 

2

abcbd

狀態: string剩  'bcbd'; pattern剩 [bcd]*b, 工作patter是[bcd]*

工作: RE 以 [bcd]* 貪婪比對,一路找到底。狀態:string 剩  '' ,pattern 剩 b

3

Failure

狀態: string剩 ''; pattern 剩 b , 工作patter是 b.

工作RE 找尾字 b,但 string 已空無字元可找,比對失敗

4

abcb

工作返回,讓工作pattern 回到[bcd]*,並將之前[bcd]* 找出字減一字元,也就是 [bcd]* 只找出 bcb,整體只找出 'abcb'

5

Failure

狀態: string剩'd'; pattern剩 b,工作patter是b

工作RE再找尾字 b,但 string 剩 'd' 找不出 b ,失敗。

6

abc

工作返回將之前[bcd]* 找出字減一字元,也就是 [bcd]* 只找出 bc,整體只找出 'abc'

6

abcb

狀態: string剩'bd'; pattern剩b,工作patter是 b. 

工作:再試b。這回找出'b'整體找到符合pattern 的 'abcb'


到 RE末端(pattern 結束)匹配出 'abcb' 。這說明了匹配引擎,會先在貪婪性匹配(比如 [bcd]*)上盡可能地把整個 string 找完,若剩下的不匹配,會返回貪婪性匹配成果的尾字元,再試剩下的匹配。如果不成功會一直試到[bcd]*找到的成果到歸零。而歸零就算失敗找不到。
 
(這段詳述了貪婪性匹配的作法和修正。Simple Patterns 後段就請看原文或機翻)



來源與參考: 
1. https://docs.python.org/3/howto/regex.html#regex-howto,Python 官網推薦文。

星期三, 11月 08, 2017

Python 檔案格式, 目錄與內容

Python 有
  1. py:  python 程式碼, 可以只是幾條 command, 或是 class 堆疊而成.
  2. pyc: 編譯後的 binary code.  import 時會導入該 binary code
  3. pyo: 最佳化(ex. 最小化) 後的 binary code, 沒有行號, 警告
  4. pyd: 相容於 windows dll [1]

Windows 下的 Python 安裝後,目錄結構為
+ Python
    . python.exe
   + DLLs
   + Doc
   + include
   + Lib
   + libs
   + Scripts
   + tcl
   + Tools

1. 常用目錄:
    使用者安裝的第三方元件, 會放在  Lib/site_packages
    比如安裝用元件, easy_install, pip. 線代運算用的 numpy,  安裝後都在 site_packages 下
    而 opencv, 直接將 opencv/build/python/XX/cv2.pyd, 放到 site_packages 下就可導入
    (XX 表示 python version)

 2. DLLs: python 使用的 dll, 以 .pyd 和 dll 提供

 3. Doc: pythonXX.chm, 詳盡的 python 說明文件

 4. include:

 5: Lib: 預設 python library, 大部分非 binary, 是程式碼 py 供使用者導入.  比如 struct.py, os.py
             而 Lib/site_packages 如前所述, 是第三方元件, 有 py, pyc, pyo, pyd.

 6. libs: windows/linux 使用的 lib
     ex.
         windows:  lpython27.lib
         linux: libpython27.a

7. Scripts
    一些一鍵安裝檔放在這?  pip.exe, easy_install.exe

8.  tcl

9. Tools

[1] Is a *.pyd file the same as a DLL?

星期六, 10月 14, 2017

安裝 pip


在 Python 上安裝元件,一鍵安裝的 pip 好用但 python 2 字輩沒內建,需動手安裝

1. 在環境變數加上 python.exe 所在目錄, 和 Scripts 所在目錄變數. 並在 Path 加上 python.exe 所在目錄,以方便之後執行 python 和 pip。
    ex:
    PYTHON27_HOME  =  D:\Python\Python27
    PYTHON27_SCRIPTS =  D:\Python\Python27\Scripts
    Path = ....; %PYTHON27_HOME%; %PYTHON27_SCRIPTS%

2. pip 官網的 get-pip.py 下載該份 get-pip.py 後,啟用 window command,
       python  get-pip.py

3. 產出 pip.exe 落在 PYTHON27_SCRIPTS 下。由於已經在 Path 加上該目錄,可直接測試
      pip

4. 更新版本
     python -m pip install --upgrade pip
   
5. 安裝後, 可使用 pip  install/uninstall/update.
在 window command 下,
> python -m pip install package_name  ← 使用 pip 安裝某套件
> python -m uninstall package_name ← 使用 pip 解除某套件
> python -m pip install --upgrage package_name ← 使用 pip 更新某套件

在 python 下,
pip install package_name 
pip uninstall package_name
pip install package_name --upgrade







參考文件
[1] How to Install Python PIP on Windows 8 / Windows 10
[2] How to download and install Python Packages and Modules with Pip

Python 在 windows 上的執行方式

初遇 python,是在良好的整合開發環境下相見。之後為了安裝其他的 python 元件,不得不從使用 python 的基本功開始。

0. 已經存在 python.exe  和  pythonw.exe 

1. 在 window command 下執行 python command  or  .py  file

    前提:
        1) 在 Path 串上 python.exe 所在路徑:
            在 控制台\系統及安全性\系統\
            找  進階系統設定\環境變數
            編輯  Path,  加上你的  python.exe 所在路徑
       2) 或者直接在 command mode 下, 移動到 python.exe 所在路徑.

    python.exe 的介面 [1]
         python [-BdEiOQsRStuUvVWxX3?] [-c command | -m module-name | script | - ] [args]    
       
         顯然我們關注怎麼用 -c 下 python command, 或執行 .py script
         以 print('a') 為例

    範例1:
        D:\Python27\python -c print('a')
        a   #果然出現 a ^^

    範例2:  python.exe 目錄下, 有 pa.py, 內容只有 print('a')
        D:\Python27\python pa
        a   #果然出現 a ^^


2. 在 python shell 下執行 python command or file
    1) 進入 shell:python
        >>> # 進去囉

    2) 離開 shell:
        >>> exit()

    3) 在 shell 下執行 python command
        >>> print('a')
        a

    4) 在 shell 下執行 python 程式碼
         >>> import pa
        a  #還記得 pa.py 嗎, 成功印出 a 了


 

參考文件
[1] Python/Doc/pythonXX.chm#Python Setup and Usage/Command line and envrionment

 
     
         

星期二, 5月 19, 2015

cornerSubPix

Camera calibration with OpenCV 有強調, 以 camera 即時取圖時,仍要有間隔,以取得不同的 image。因為相似的 image 會導致 similar equations,而 similar equations 在校正階段,會導致 ill-posed problem。文中建議, findChessboardCorerns 後,再用 cornerSubPix 再找 image points。

Similar position 導致的 similar equation 的破壞力究竟多大?我還不確定。本來以為只是會 over-fitting 某些視角。但目前只要相似圖,undistortion 的結果就很慘。而相近的那幾張圖也沒有特別好。

文中建議的 cornerSubPix 指出,我們所面對的 image points,不該用有限解析度的整數點位置,而是有小數點的真實位置。學習重點:
1) cornerSubPix 的使用
2) 逼近 "真實位置" 的原理
3) findChessboard 如果不用 fast mode,內部是否已使用 cornerSubPix ?


1) cornerSubPix 的使用
C++: void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteriacriteria)
Python: cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria) → None

image: input image . opencv 2.4.9 仍是用 gray image

corners : 重要的兼 input 和 output。本例中將 findChessboard 得到的 image points 傳入,結束後得到修正結果。opencv 2.4.9 仍是用 vector. Point2d 馬上 throw error。

size: winSize。實際對每角點的搜尋區大小是 (winSize*2+1, winSize*2+1)。

zeroZone: 搜索区域中间的dead region边长的一半,有时用于避免自相关矩阵的奇异性。如果值设为(-1,-1)则表示没有这个区域

criteria: 停止條件。cornerSubPix 是遞迭式,可設最多幾回 criteia.maxCount 或角點的回合位移小於 criteria.epsilon,若回合內移動太小,沒必要再算就停止。

2) 逼近 "真實位置" 的原理
先說 gradient 與 edge 的關係。在理想的 edge 上,p 點的梯度,與自身的 edge 方向垂直。對在同 edge 上的 q,可寫成  G(p)^t  (q - p) = 0。其中 G(p) 是 p 之梯度。
回到本題,我們想找角點 q 落在 p 附近。對 p 附近的 pi 點,已知對應梯度 D Ipi。 (這裡困惑了,貌似 pi 都該在 edge 上,但圖中 p0 顯然不在 edge 上?),角點 q 也落在這些 edge 上,所以滿足  G(pi)^t  (q - pi) = 0。

命題為找角點 q 盡可能讓 pi 梯度能垂直所有的 (pi - q)

對 searching window,加總求 q 能使 epsilon i sum 最小 

find q min. sum DIpi^t  (q - pi)

 這邊應可直接用 least square 解 q。


不過文件說用 iterative 解,可能是我們大約知道 q 的位置。文件說法,讓下式為 0




3) findChessboard 如果不用 fast mode,內部是否已使用 cornerSubPix ?
是。trace cvFindChessboardCorners(),至少在 2.4.6 版,非 fast mode,就會進入 cvFindCornerSubPix()。



星期六, 5月 09, 2015

opecv:error C2668 "cv::write" ambiguous call to overloaded function

error C2668: "cv::write" : ambiguous call to overloaded function
VC2008 之 error C2668: "cv::write" : ambiguous call to overloaded function

改 size_t 後,opencv 常送出 ambiguous call 的 error message。
乍見這類錯誤很惶恐,發生在 OpenCV 提供的 template function,
不是自己能控制的,要如何訂正呢?還好從 output 可以看出端倪。

編譯過程中的 Output window, 找出 error C2668 的上下文
..operations.hpp(2911): error C2668: 'cv::write' : ambiguous call to overloaded function
..operations.hpp(2709): could be 'void cv::write(cv::FileStorage &,const std::string &,double)'
..operations.hpp(2708): or       'void cv::write(cv::FileStorage &,const std::string &,float)'
..operations.hpp(2707): or       'void cv::write(cv::FileStorage &,const std::string &,int)'
while trying to match the argument list '(cv::FileStorage, std::string, const size_t)'
.\ex_tracer.cpp(377) : see reference to function template instantiation 'cv::FileStorage &cv::operator <<(cv::FileStorage &,const _Tp &)' being compiled
with
[
    _Tp=size_t
]

引發 error 之 source code 是下段
FileStorage fs(fname, FileStorage::WRITE);
for (size_t i = 0; i < V.size(); ++i) {
  ..
  fs << "vid" << i; // => 出現 ERROR c2668
}
.............................................................................
原來是 for_loop 中使用 size_t i, 使得 fs 困惑了. 
這類  write::(fs, name, value),
fs 只吃 double, float, int, 不接受 size_t.

size_t 轉型為 int 即可.
fs << "vid" << (int) i;  // 正確,不再出現 ERROR c2668

MFC:在 Dialog 中使用 CToolBar 的 tooltip (vc++)

許久之前遇上一個問題 - MFC 的 Dialog 中, 為何 CToolBar 的 tooltip 無效? 

在網路上轉了半天, 盯著 MSDN 的 CBRS_TOOLTIPS 發呆, 
想說這個不就是會讓 tooltip 閃閃發亮的參數嗎? 
實際上, CBRS_TOOLTIPS 對 docuement/view 的 SDI/MDI 都有效, 
但 CDialog 沒有處理對應 message 的 message handler, 

還好網上早有高人解答, 只要增加 TTN_NEEDTEXTW, TTN_NEEDTEXTA 的 message handler.
為了紀念轉了四五個小時的搜尋, 不只引用, 也鄭重地貼上原文:
http://www.wangchao.net.cn/bbsdetail_748638.html

改編
CToolBar 一般用在 SDI 或是 MDI, 
如果我們在一個Dialog里新建了一個CToolBar,它的提示信息可能就沒有辦法出來了。
主要的原因是由於我們沒有為這個CToolBar寫提示信息的消息映射函數。 如果要增加的話,

0) 設定 tooltips 給 toolbar, 設定 toolbar button 之 prompt
1) 建立 message mapping
2) 建立 message handler
3) 加上 header

0.1 ToolBar 設定為有 tooltips
CToolBar mToolBar;
mToolBar.Create(this, AFX_DEFAULT_TOOLBAR_STYLE| CBRS_TOOLTIPS);
0.2 在 ToolBar button 的屬性 prompt, 加上對應之 tooltip
1. 建立消息映射
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, OnToolTipText) 
ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, OnToolTipText) 
2. 增加 message handler OnToolTipText()
afx_msg BOOL OnToolTipText( UINT id, NMHDR * pNMHDR, LRESULT * pResult ); 
BOOL MyDlg::OnToolTipText(UINT nFlags, NMHDR* pNMHDR, LRESULT* pResult)
{
ASSERT(pNMHDR->code == TTN_NEEDTEXTA || pNMHDR->code == TTN_NEEDTEXTW);
// if there is a top level routing frame then let it handle the message
if (GetRoutingFrame() != NULL) return FALSE;
// to be thorough we will need to handle UNICODE versions of the message also !!
TOOLTIPTEXTA* pTTTA = (TOOLTIPTEXTA*)pNMHDR;
TOOLTIPTEXTW* pTTTW = (TOOLTIPTEXTW*)pNMHDR;
TCHAR szFullText[512];
CString strTipText;
UINT nID = pNMHDR->idFrom;
if (pNMHDR->code == TTN_NEEDTEXTA && (pTTTA->uFlags & TTF_IDISHWND) ||
pNMHDR->code == TTN_NEEDTEXTW && (pTTTW->uFlags & TTF_IDISHWND))
{
// idFrom is actually the HWND of the tool 
nID = ::GetDlgCtrlID((HWND)nID);
}
if (nID != 0) // will be zero on a separator
{
AfxLoadString(nID, szFullText);
strTipText=szFullText;
#ifndef _UNICODE
if (pNMHDR->code == TTN_NEEDTEXTA)
{
lstrcpyn(pTTTA->szText, strTipText, sizeof(pTTTA->szText));
}
else
{
_mbstowcsz(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
}
#else
if (pNMHDR->code == TTN_NEEDTEXTA)
{
_wcstombsz(pTTTA->szText, strTipText,sizeof(pTTTA->szText));
}
else
{
lstrcpyn(pTTTW->szText, strTipText, sizeof(pTTTW->szText));
}
#endif
*pResult = 0;
// bring the tooltip window above other popup windows
::SetWindowPos(pNMHDR->hwndFrom, HWND_TOP, 0, 0, 0, 0,
SWP_NOACTIVATE|SWP_NOSIZE|SWP_NOMOVE|SWP_NOOWNERZORDER);
return TRUE;
}
return FALSE;
}
3.增加一個頭文件 // 不確定是否必要
  #include  

opencv:How to access a Mat with multiple channels ?

Mat.at(row, col) , 雖然每次都得從頭算出位址, 是效率不高的存取方式,
但頗好用. 只是, 非單一 channel 的 matrix 要如何存取呢?

下文 testM 是有三個 channel 的 8-bits unsign char matrix.
可依舊以 (row, col) 存取, 但最小單位是 Vec3b


        Mat testM(3,4,CV_8UC3);
for (int i = 0; i < testM.rows; i++)
{
for (int j = 0; j < testM.cols; j++)
{
Vec3b v = testM.at(i,j);
v[0] = i;
v[1] = i+10;
v[2] = i+20;
testM.at(i,j) = v;
}
}

當然也可直接存取 data, serial data 如下

row0= {ch0 ch1 ch2}, {ch0 ch1 ch2}, {ch0 ch1 c2}, {ch0 ch1 ch2}
row1= {ch0 ch1 ch2}, {ch0 ch1 ch2}, {ch0 ch1 c2}, {ch0 ch1 ch2}  
row2= {ch0 ch1 ch2}, {ch0 ch1 ch2}, {ch0 ch1 c2}, {ch0 ch1 ch2}      
for (int i = 0; i < testM.rows; i++)
{
uchar* pdata = testM.data + i*testM.step;
int k = 0;
for (int j = 0; j < testM.cols; j++, k+=3)
{
printf("r=%d,c=%d: %d,%d,%d\n", i, j, pdata[k],pdata[k+1],pdata[k+2]);
}
}

輸出:
r=0,c=0: 0,10,20
r=0,c=1: 0,10,20
r=0,c=2: 0,10,20
r=0,c=3: 0,10,20
r=1,c=0: 1,11,21
r=1,c=1: 1,11,21
r=1,c=2: 1,11,21
r=1,c=3: 1,11,21
r=2,c=0: 2,12,22
r=2,c=1: 2,12,22
r=2,c=2: 2,12,22
r=2,c=3: 2,12,22

CUDA:Can not find cutil32D.lib ...

Problem :  SDK (e.g. OpenCV, OptiX) 和本機 CUDA  32 bits or 64 bits 間選用了不同平台.

Solution 

step 1 :重新編譯適當平台的 cutil library.  位在 
C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.0\CUDALibraries\common\ 

step 2 : 將不同平台產生的 cutil32D.lib/cutil64D.lib 加入 linker   
Linker -> General -> Additional Library Directories 

由於 step 1 不同平台的 library 會置於不同 path, 將有平台變數的 path

  
 $(NVSDKCOMPUTE_ROOT)\C\common\lib\$(PlatformName)
   $(NVSDKCOMPUTE_ROOT)\shared\lib\$(PlatformName)
加入 Linker -> General -> Additional Library Dire

p.s. 
 win7 找環境變數 …
電腦 -> 變更設定 -> 系統內容 -> 環境變數
NVSDKCOMPUTE_ROOT=C:\ProgramData\NVIDIA Corporation\NVIDIA GPU Computing SDK 4.1

Step 3 : 如果不幸地出現因 cutil 引起的 error lnk2005 … already define in LIBCMTD.lib
        [Debug/Win32]
        1.  C++ 改用 /MTd 編譯
                C/C++ -> Code Generation change the Runtime Library to/MTd        2.  忽略 LIBCMT.lib
                Linker->Input->Ignore Specific Library to  libcmt.lib
        3.   CUDA 的 Host code (CPU code) 也以  /MTd 編譯                        CUDA Runtime API -> Host -> Runtime Library => /MTd

                [Release/Win32]
                1.  C++ 改用 /MT 編譯
                        C/C++ -> Code Generation change the Runtime Library to /MT
                2.  忽略 LIBCMTD.lib
                        Linker->Input->Ignore Specific Library to  libcmtd.lib 
                3.   CUDA 的 Host code (CPU code) 也以  /MT 編譯                       CUDA Runtime API -> Host -> Runtime Library => /MTd 
             

        p.s
. 曾經同時忽略 libcmt.lib 和 libcmtd.lib, 反而出現更多 error lnk2005 ! 

Reference link