RainMan二值化製做(圖形,視窗,拉軸實作)
#include <stdio.h>
#include <stdlib.h>
#include <cv.h>
#include <highgui.h>
void * WindowHandle1;
char FileName[]="rain.jpg";
char TrackbarName[]="Threshold";
int TrackbarInitValue=180;
int TrackbarStopValue=255;
IplImage *Image1;
IplImage *Image2;
CvSize Image2Size;
void onTrackbar(int position);
int main()
{
Image1 = cvLoadImage(FileName,CV_LOAD_IMAGE_GRAYSCALE);
Image2Size = cvSize(Image1->width,Image1->height);
Image2 = cvCreateImage(Image2Size,IPL_DEPTH_8U,1);
cvNamedWindow("Show Image",0);
cvMoveWindow("Show Image",0,0);
cvResizeWindow("Show Image",300,400);
cvCreateTrackbar(TrackbarName,"Show Image",
&
TrackbarInitValue,TrackbarStopValue,onTrackbar);printf("Now, Trackbar position is : %d\n",cvGetTrackbarPos(TrackbarName,"Show Image"));
cvSetTrackbarPos(TrackbarName,"Show Image",177);
WindowHandle1=cvGetWindowHandle("Show Image");
printf("The Window Handle is : %d\n",WindowHandle1);
printf("The Window Name is : %s\n",cvGetWindowName(WindowHandle1));
cvShowImage("Show Image",Image1);
cvWaitKey(0);
cvDestroyWindow("Show Image");
cvReleaseImage(
&
Image1);cvReleaseImage(
&
Image2);}
void onTrackbar(int position)
{
cvThreshold(Image1,Image2,position,255,CV_THRESH_BINARY);
cvShowImage("Show Image",Image2);
}
執行結果:

跟前一篇程式碼比起來,這邊多創造了IplImage資料結構的Image2及一個CvSize資料結構的Image2Size,然後初始化Image2Size的大小為Image1的寬跟高,再用cvCreateImage()初始化Image2的圖形空間,這邊給Image2,8位元1個通道非負整數空間,也就是開了一個非負整數0~255的二維陣列,設立一個新的視窗,加上了cvCreateTrackbar()的函式,而使用cvCreateTrackbar()必須要給予Trackbar一個事件,事件的命名可以自由的取名字,這裡給它的事件名稱是void onTrackbar(int postion),預設Trackbar的位置在180,最大拉軸長度是255,用cvGetTrackbarPos()查看拉軸位置,再用cvSetTrackbarPos()重新定位拉軸位置為177,接著,在onTrackbar()中放入了cvThreshold()演算法函式,再用cvSohwImage()顯示二值化的結果.要注意的是,設定事件名稱的時候最好也符合命名規則,增加可讀性,在這邊OpenCV可寫的事件比一般GUI介面還少很多,如果有瞭解過GUI的事件(Event),大概就曉得為啥要這樣設計.
接著逐一介紹各副程式的功能,從"highgui.h"的開始:
cvCreateTrackbar()
創立一個Trackbar在目標視窗上,起始值從0開始,而Trackbar指標開始的位置跟Trackbar最大值要自己設定,再給他一個可控制的事件名稱,此Trackbar事件可自由命名,但是務必要讓他輸入一個int型別的變數如:void xxx(int position).
cvCreateTrackbar("Trackbar名稱","目標視窗名稱",指標開始數值,Trackbar最大值,Trackbar事件副程式名稱);
cvGetTrackbarPos()
檢視Trackbar的位置,需要給它Trackbar的名稱,目標視窗名稱.
int cvGetTrackbarPos("Trackbar名稱","目標視窗名稱");
cvSetTrackbarPos()
重新設定Trackbar的位置,需要給它Trackbar的名稱,目標視窗名稱.
cvGetTrackbarPos("Trackbar名稱","目標視窗名稱",新的拉軸位置數據);
接下來都非highgui.h的函式
cvSize()
初始化CvSize資料結構,放置長跟寬的整數值
CvSize cvSize(寬的數值,高的數值);
cvCreateImage()
初始化IplImage資料結構,創造一個空白的圖片基本的格式,格式內容可參考命名規則,再給他通道數(二維陣列的數目).
cvCreateImage(CvSize資料結構,IPL_DEPTH_系列參數,通道數);
onTrackbar()
自行定義名稱,主要是接收拉軸移動後的數值,此數值做為二值化的門檻值,通常拉軸移動的數值都是做為各個演算法的門檻值之用.
void onTrackbar(拉軸移動整數值);
cvThreshold()
此為演算法功能之ㄧ,跟門檻值相關的演算法蒐集的副程式,第一個引數為輸入圖,第二個引數為計算結果的圖,再來是門檻最大值,二值化門檻值參數.
cvThreshold(原始圖形IplImage資料結構,計算後結果IplImage資料結構,門檻值,最大門檻值數值,CV_THRESH_BINARY);
9 意見:
你好
我有一個疑問
在程式中並無回圈再檢查bar的位置改變
但程式執行時當你移動bar時
圖的結果卻會跟這改變
這倒底是什麼原因造成的
謝謝
這是一種Win32 api事件佈署的寫法~
用到的是多執行緒(Multi-thread),可以藉由
cvCreateTrackbar(TrackbarName,"Show Image",&TrackbarInitValue,TrackbarStopValue,onTrackbar);
佈置(delegation)要觸發的事件
在交由這個process底下的Multi-thread來做處理~
您好,我照您的方法執行程式,但出來的圖卻是灰階的,而不是黑白的,這是為什麼呢?
會是灰階是因為中間多了一行cvShowImage("Show Image",Image1);
把它改成Image2,
或是註解掉就可以,
但是我移動Trackbar時windows會有記憶體錯誤的情況,不知道哪錯了(OpenCV 2.0)
您好
我執行時為何一拉BAR程式就當掉了呢?
謝謝教導
移動Trackbar出錯
後來發現是 Img1跟Img2 的channel要設一樣,img1 channel=3,所以img2 設1會錯
不知道是不是版本的問題我試用opencv 1.0
我也是....移動bar就出錯
2.0拉bar造成的錯誤 我用2.1就好了
您好~請問門檻值177是怎麼定義出來的呢?
張貼留言