IplImage資料結構二值化實作
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
double Red[512][384];
double Green[512][384];
double Blue[512][384];
double Gray[512][384];
int main()
{
int Height;
int Width;
int Threshold=64;
IplImage *Image1,*Image2;
Image1=cvLoadImage("bower.jpg",1);
Image2=cvCloneImage(Image1);
CvScalar Scalar1;
Height=cvGetDimSize(Image1,0);
Width=cvGetDimSize(Image1,1);
/*Load Image RGB Values*/
for(int i=0;i<Height;i++)
{
for(int j=0;j<Width;j++)
{
Scalar1=cvGet2D(Image1,i,j);
Blue[i][j]=Scalar1.val[0];
Green[i][j]=Scalar1.val[1];
Red[i][j]=Scalar1.val[2];
}
}
/*Implement Algorithms*/
for(int i=0;i<Height;i++)
{
for(int j=0;j<Width;j++)
{
Gray[i][j]=0.299*Red[i][j] + 0.587*Green[i][j] + 0.114*Blue[i][j];
if(Gray[i][j]<Threshold)
{
Red[i][j]=0;
Green[i][j]=0;
Blue[i][j]=0;
}
else
{
Red[i][j]=255;
Green[i][j]=255;
Blue[i][j]=255;
}
}
}
/*Save Image RGB Values*/
for(int i=0;i<Height;i++)
{
for(int j=0;j<Width;j++)
{
Scalar1=CV_RGB(Red[i][j],Green[i][j],Blue[i][j]);
cvSet2D(Image1,i,j,Scalar1);
}
}
cvNamedWindow("Bower Thresholding",1);
cvShowImage(Bower Thresholding",Image1);
cvNamedWindow("Bower",1);
cvShowImage("Bower",Image2);
cvWaitKey(0);
}
執行結果:
上面的程式使用了cvCloneImage()複製了一份原始圖片,而RGB演算法的使用上相較之下已經比imageData的方式簡單許多了,而imageData也因此被包在下一層做運算了,這邊除了用到了前面所提到的cvGet2D()跟cvSet2D()做運算,還設計了灰階的轉換,而對灰階做一個門檻值非黑即白就是二值化的製作了跟前面那篇"GUI介面的製作-Trackbar製作"的cvThreshold()是同一個演算法,而中間/*Implement Algorithms*/的部份,就可以自由的存取RGB值了!
這裡再提到幾個重要的部份,這部份做存取RGB值的操作,會有許多的問題及瓶頸,今天假設要存取的圖片是1000*1300大小的維度,使用一般的二維陣列存取RGB值一定會爆掉,因為RGB陣列的宣告是存在靜態Stack空間的,對編譯器而言,Stack空間是有限的,而在編譯的一開始編譯器就設定了Stack空間的大小,因此解決的方法,除了去編譯器的環境設定下調整Stack空間的大小,要不然就是要使用二維動態陣列了,而且使用動態二維陣列,也可以在不曉得圖片大小的情況下實作二維陣列,動態陣列屬於Heap的空間,當Heap空間不夠的時候會被分頁替換,對Heap空間來講,其實是沒上限的,但在使用上Heap會比Stack慢,而CvMat,IplImage其實就是一種Heap的實作之一.簡而言之,資料結就是使用到Heap空間.
另一個部分是分頁錯誤的問題,今天假如上面的程式碼,寬在第一層for迴圈,高在第二層for迴圈,會嚴重的影響程式的效能,因為他中間做了更多次的分頁替換,對for迴圈來講,每做一次就會錯一次,對一個二維陣列的存取來說,不該有這種情形發生,詳細的說明可以去參考作業系統原理分頁替換的部分.
cvCloneImage()
複製一份完整的IplImage資料結構圖形及設定
cvCloneImage(IplImage資料結構)
3 意見:
hi,yester
代码中写错了:
cvNamedWindow("Bower Thresholding",1);
cvShowImage(Bbower Thresholding",Image1);
我改了20分钟,才发现拼写错了
感謝指正~
您好,為什麼我執行出來結果
處理後的圖會有部分是重複的呢??
張貼留言