2013年7月9日
#
DirectUI 控件,具有簡單,可擴展性好等的特點,但是實際開發的時候,遇到復雜的控件,還是喜歡WIN32窗口句柄模式寫控件,原因有如下幾個
1、消息隊列具有線程的安全性。
2、不需要考慮FOCUS,SIZE,MOVE,PAINT,MOUSE,KEY這些框架消息的DISPATCH
3、和已經有的MFC,WIN32代碼融合的時間比較少。
2013年4月16日
#
Dark Channel Prior去霧的算法,下載了個現成的測試一下,果然效果不錯,效果如下。
百度文庫里的文檔
http://wenku.baidu.com/view/eae99905bed5b9f3f90f1cfd.html
測試圖像,

結果圖像
2013年2月21日
#
寬度W,高度H 的圖像,做膨脹操作,如果膨脹的結構元素structure element,大小為kw,kh,那么就需要做W*H*kw*kh次運算,運算量比較大。
根據圖像形態學的理論,膨脹滿足結合律,即
,B和C為結構元素。假設一個結構元素S可以表示為兩個結構元素B和C的膨脹,即S=B⊕C,則A⊕S=A⊕(B⊕C)=(A⊕B)⊕C,換言之,用S膨脹A等同于用B先膨脹A,再用C膨脹前面的結果。我們稱S能夠分解成B和C兩個結構元素。結合律很重要,因為計算膨脹所需要的時間正比于結構元素中的非零像素的個數。通過上述推導,分解結構元素,然后再分別用子結構元素進行膨脹操作往往會實現很客觀的速度的增長。
同樣,腐蝕也可以做結構分解,腐蝕滿足公式
,B和C為結構元素,同樣如果一個結構元素S可以表示為兩個結構元素B和C的膨脹,即S=B⊕C,那么用S腐蝕A等同于用B先腐蝕A,再用C腐蝕前面的結果。公式推導省略。
圖像形態學膨脹和腐蝕介紹,可見
http://en.wikipedia.org/wiki/Erosion_(morphology)
http://en.wikipedia.org/wiki/Dilation_(morphology)
做結構分解后的運算量為W*H*(kw+kh)
代碼如下
1
#include <cv.h>
2
#include <highgui.h>
3
#include <stdio.h>
4
5
6
int main(int argc, char** argv)
7

{
8
if(argc<2)
{
9
printf("has no param\n");
10
return 0;
11
}
12
13
IplConvKernel *element1 = cvCreateStructuringElementEx( 1, 25, 0, 0, CV_SHAPE_RECT, 0);
14
IplConvKernel *element2 = cvCreateStructuringElementEx( 16, 1, 0, 0, CV_SHAPE_RECT, 0);
15
IplConvKernel *element3 = cvCreateStructuringElementEx( 16, 25, 0, 0, CV_SHAPE_RECT, 0);
16
17
IplImage* src=cvLoadImage(argv[1],1);
18
19
20
if( src!= NULL)
21
{
22
23
IplImage* img = cvCreateImage(cvGetSize(src),IPL_DEPTH_8U,1);
24
cvCvtColor(src,img,CV_BGR2GRAY);
25
cvReleaseImage(&src);
26
27
28
IplImage* tmp = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
29
cvDilate( img, tmp, element1, 1);
30
31
IplImage* dst1 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
32
cvDilate( tmp, dst1, element2, 1);
33
34
35
IplImage* dst2 = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
36
cvDilate( img, dst2, element3, 1);
37
38
IplImage* diff = cvCreateImage(cvGetSize(img),IPL_DEPTH_8U,1);
39
cvSub(dst2,dst1,tmp,NULL);
40
cvEqualizeHist( tmp, diff);
41
cvReleaseImage(&tmp);
42
43
int noZeroCount=cvCountNonZero(diff);
44
printf("no zerocount %d\n",noZeroCount);
45
46
47
cvNamedWindow("img",CV_WINDOW_AUTOSIZE);
48
cvShowImage("img",img);
49
cvNamedWindow("dst1",CV_WINDOW_AUTOSIZE);
50
cvShowImage("dst1",dst1);
51
cvNamedWindow("dst2",CV_WINDOW_AUTOSIZE);
52
cvShowImage("dst2",dst2);
53
cvNamedWindow("diff",CV_WINDOW_AUTOSIZE);
54
cvShowImage("diff",diff);
55
56
57
cvWaitKey();
58
cvDestroyAllWindows();
59
60
61
cvReleaseImage(&img);
62
cvReleaseImage(&dst1);
63
cvReleaseImage(&dst2);
64
cvReleaseImage(&diff);
65
66
cvReleaseStructuringElement(&element1);
67
cvReleaseStructuringElement(&element2);
68
cvReleaseStructuringElement(&element3);
69
70
71
72
73
74
}
75
else
76
{
77
printf("error,not load\n");
78
}
79
return 0;
80
};
81
2012年8月18日
#
2011年12月5日
#
對N項數據進行判斷,生成N項結果,這些結果中有YES,也有NO,采用何種方法,產生最后結果。
0. 努力使結果一致
在判斷之前,對N項數據過濾,看是否出現異常,去掉那些因為數據異常而產生的結果,努力使所有結果一致,全是YES或全是NO,當然這就困難了。
1.單值判斷
1.1 嚴格判斷,只要有一項結果為NO,就認為最后結果為NO。
1.2 寬松判斷,只要有一項結果為YES,就認為最后結果為YES。
2. 對出現的兩類結果次數進行比較,選擇出現次數多的那項。
3. 根據重要程度來判斷。先數值化結果,使YES的值為1,NO的值為0。然后再根據數據的重要程度,定義一些數值,稱為重要因子。每項數據產生的數值結果乘以對應的重要因子,再相加這些結果,得出的和值,與給定的閾值相比較,得出最后結果。
2011年6月7日
#
SkinLib的代碼簡單明了,對于想學習和了解UI Skin的原理來說是合適的. 相關鏈接如下
http://www.shnenglu.com/netboy/archive/2009/02/15/73863.html
CSkinDialog 使用Hook,WndProc技術,重載原有繪制消息過程.
CSkinDialog的區域分為客戶區域和非客戶區域,CSkinDialog的非客戶區域又被分為如下幾個子區域,
1.左邊緣,m_nToLeft為窗口的左邊緣長度.
2.右邊緣,m_nToRight為右邊緣的長度.
3.Caption區域,m_nToTop 為其高度,Caption 區域又可以分為
3.1.(0,0,m_nTopLeft,m_nToTop)
3.2.標題區域 (m_nTopLeft,0,rcWnd.Width()-m_nTopRight,m_nToTop)
3.3.close,max,min 按鈕區域
4.下部邊緣,m_nToBottom為下部邊緣的高度
根據配置文件,讀取到相應的Skin,繪制上述Dialog幾個子區域.
1.DrawBorder繪制左,右,下部邊緣.
2.DrawCaption繪制Caption區域.
2011年6月6日
#
Affine ,Perspective變形 資源很多,
可以查看OpenCV
不規則變形
http://paulbourke.net/miscellaneous/imagewarp/
鼠標拉伸改變圖像的
http://www.codeproject.com/KB/graphics/localimagewarper.aspx?q=warp
Photoshop液化工具箱中向前變形工具
http://www.cnblogs.com/xiaotie/archive/2009/12/08/1619046.html
2011年2月16日
#
如果在.net中一個線程等待另外一個線程的完成,可以使用System.Threading.Thread.Join, 在Win32 下的相應的等效代碼
1 WaitForSingleObject(hThread,INFINITE);
2
3 CloseHandle(hThread);
Win32 中CreateThread出來的hThread屬于整個Process,線程中的回調函數結束后,不會失效,只有調用者調用CloseHandle,才最后真正的釋放系統中Thread 的資源.
如果線程的回調函數已經結束,那么hThread 處于激活狀態,WaitForSignleObject 便能獲取到當前狀態,成功返回;如果沒有,WaitForSignleObject 便一直等待線程的回調結束.
如果你想一個線程中等待另外一個線程回調結束的同時,進行消息MSG的分發,或者做其他的事情.例如主UI線程在等待工作線程完成的同時,需要更新UI上的進度條,這時可以讓工作線程發送進度消息MSG給主UI線程,主UI線程接受到消息MSG更新UI.可以在主UI線程中使用MsgWaitForMultipleObjects函數達到這一效果,
1 MSG msg;
2
3 BOOL bLoop=TRUE;
4
5 while(bLoop)
6 {
7
8 int nWait=MsgWaitForMultipleObjects(1,&hThread,FALSE,3000,QS_ALLEVENTS);
9 switch(nWait)
10 {
11 case WAIT_TIMEOUT:
12 case WAIT_OBJECT_0+1:
13 {
14 while( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) ) {
15 TranslateMessage(&msg);
16 DispatchMessage( &msg );
17 }
18 break;
19 }
20
21 case WAIT_OBJECT_0:
22 default:
23 bLoop=FALSE;
24 break;
25 }
26 };
27 CloseHandle(hThread);
28
29
30
2011年1月18日
#
代碼下載鏈接如下,
http://www.shnenglu.com/Files/mcs51a/blobcounter.rar
代碼中涉及到的DIB操作 是8Bit 的二值圖像.
2010年9月15日
#
CreateThread,是WIN32 最直接創建的thread API函數.但是如果在線程回調(CALLBACK)函數中使用一些標準C的函數,當線程正常退出的時候,即使你釋放了所有用戶資源,仍然會有資源的泄漏的隱患。主要原因是線程中都需要有額外的資源,來保證一些標準C函數的線程安全,這些資源的創建是在C的標準函數被調用的時候,但是在thread退出的時候,沒法通過正常途徑釋放。
如果在你的回調函數中使用一些標準C函數,最好使用_beginthreadex,_endthreadex替換掉原來的CreateThread, _endthreadex 會釋放這些資源,或者AfxBeginThread(里面有調用_beginthreadex,_endthreadex)
具體原因查看《程序員的修養,編譯與鏈接》一書。