OpenCV分配与释放图像空间
生活随笔
收集整理的這篇文章主要介紹了
OpenCV分配与释放图像空间
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
圖像處理
單通道圖像灰度取值
IplImage * pSrcImage = cvLoadImage("Sunset.jpg",CV_LOAD_IMAGE_GRAYSCALE);
uchar * pSrcData = (uchar *)pSrcImage->imageData;
for (int i = 0; i < pSrcImage->height; i++)
? ?{
? ?? ?for (int j = 0; j < pSrcImage->width; j++)
? ?? ?{
? ?? ?? ?int n = i * pSrcImage->width + j;
? ?? ?? ?char a = pSrcData[n];// 這個即是像素值
? ?? ?}
? ?}
cvReleaseImage(&pSrcImage);
?
分配與釋放圖像空間
?
- 分配圖像空間:IplImage* cvCreateImage(CvSize size, int depth, int channels);
?? size:?? cvSize(width,height);
?? depth: IPL_DEPTH_8U, IPL_DEPTH_8S, IPL_DEPTH_16U,
????????? IPL_DEPTH_16S, IPL_DEPTH_32S, IPL_DEPTH_32F, IPL_DEPTH_64F
?? channels: 1, 2, 3 or 4.
???? 注意數據為交叉存取.彩色圖像的數據編排為b0 g0 r0 b1 g1 r1 ...舉例:
// 分配一個單通道字節圖像
IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
// 分配一個三通道浮點圖像
IplImage* img2=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);?
- 釋放圖像空間:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
cvReleaseImage(&img);?
- 復制圖像:IplImage* img1=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
IplImage* img2;
img2=cvCloneImage(img1);?
- 設定/獲取興趣區域:void?? cvSetImageROI(IplImage* image, CvRect rect);
void?? cvResetImageROI(IplImage* image);
vRect cvGetImageROI(const IplImage* image);
大部分OpenCV函數都支持ROI.?
- 設定/獲取興趣通道:void cvSetImageCOI(IplImage* image, int coi); // 0=all
int cvGetImageCOI(const IplImage* image);
大部分OpenCV函數暫不支持COI.?
?
讀取存儲圖像
?
- 從文件中載入圖像:?? IplImage* img=0;
?? img=cvLoadImage(fileName);
?? if(!img) printf("Could not load image file: %s\n",fileName);
?? Supported image formats: BMP, DIB, JPEG, JPG, JPE, PNG, PBM, PGM, PPM,
??????????????????????????? SR, RAS, TIFF, TIF載入圖像默認轉為3通道彩色圖像. 如果不是,則需加flag:
?? img=cvLoadImage(fileName,flag);
?? flag: >0 載入圖像轉為三通道彩色圖像
???????? =0 載入圖像轉為單通道灰度圖像
???????? <0 不轉換載入圖像(通道數與圖像文件相同).?
- 圖像存儲為圖像文件:?? if(!cvSaveImage(outFileName,img)) printf("Could not save: %s\n",outFileName);
輸入文件格式由文件擴展名決定.
?
?
存取圖像元素
?
- 假設需要讀取在i行j列像點的第k通道. 其中, 行數i的范圍為[0, height-1], 列數j的范圍為[0, width-1], 通道k的范圍為[0, nchannels-1].
?
- 間接存取:(比較通用, 但效率低, 可讀取任一類型圖像數據)
?
- 對單通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("intensity=%f\n",s.val[0]);
s.val[0]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value?
- 對多通道浮點或字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
CvScalar s;
s=cvGet2D(img,i,j); // get the (i,j) pixel value
printf("B=%f, G=%f, R=%f\n",s.val[0],s.val[1],s.val[2]);
s.val[0]=111;
s.val[1]=111;
s.val[2]=111;
cvSet2D(img,i,j,s); // set the (i,j) pixel value?
?
- 對單通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- 直接存取:(效率高, 但容易出錯)
?
- 對單通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
((uchar *)(img->imageData + i*img->widthStep))[j]=111;?
- 對多通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((uchar *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R?
- 對多通道浮點圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 0]=111; // B
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 1]=112; // G
((float *)(img->imageData + i*img->widthStep))[j*img->nChannels + 2]=113; // R?
?
- 對單通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- 用指針直接存取 :(在某些情況下簡單高效)
?
- 對單通道字節圖像:IplImage* img?? = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
int height????? = img->height;
int width?????? = img->width;
int step??????? = img->widthStep/sizeof(uchar);
uchar* data???? = (uchar *)img->imageData;
data[i*step+j] = 111;?
- 對多通道字節圖像:IplImage* img?? = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
int height????? = img->height;
int width?????? = img->width;
int step??????? = img->widthStep/sizeof(uchar);
int channels??? = img->nChannels;
uchar* data???? = (uchar *)img->imageData;
data[i*step+j*channels+k] = 111;?
- 對單通道浮點圖像(假設用4字節調整):IplImage* img?? = cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
int height????? = img->height;
int width?????? = img->width;
int step??????? = img->widthStep/sizeof(float);
int channels??? = img->nChannels;
float * data???? = (float *)img->imageData;
data[i*step+j*channels+k] = 111;?
?
?
- 對單通道字節圖像:IplImage* img?? = cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
- 使用 c++ wrapper 進行直接存取:(簡單高效)
?
- 對單/多通道字節圖像,多通道浮點圖像定義一個 c++ wrapper:template<class T> class Image
{
?? private:
?? IplImage* imgp;
?? public:
?? Image(IplImage* img=0) {imgp=img;}
?? ~Image(){imgp=0;}
?? void operator=(IplImage* img) {imgp=img;}
?? inline T* operator[](const int rowIndx) {
???? return ((T *)(imgp->imageData + rowIndx*imgp->widthStep));}
};
typedef struct{
?? unsigned char b,g,r;
} RgbPixel;
typedef struct{
?? float b,g,r;
} RgbPixelFloat;
typedef Image<RgbPixel>??????? RgbImage;
typedef Image<RgbPixelFloat>?? RgbImageFloat;
typedef Image<unsigned char>?? BwImage;
typedef Image<float>?????????? BwImageFloat;?
- 單通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,1);
BwImage imgA(img);
imgA[i][j] = 111;?
- 多通道字節圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_8U,3);
RgbImage?? imgA(img);
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;?
- 多通道浮點圖像:IplImage* img=cvCreateImage(cvSize(640,480),IPL_DEPTH_32F,3);
RgbImageFloat imgA(img);
imgA[i][j].b = 111;
imgA[i][j].g = 111;
imgA[i][j].r = 111;?
?
- 對單/多通道字節圖像,多通道浮點圖像定義一個 c++ wrapper:template<class T> class Image
?
圖像轉換
?
- 轉為灰度或彩色字節圖像:cvConvertImage(src, dst, flags=0);
?? src = float/byte grayscale/color image
?? dst = byte grayscale/color image
?? flags = CV_CVTIMG_FLIP????? (flip vertically)
?????????? CV_CVTIMG_SWAP_RB?? (swap the R and B channels)?
- 轉換彩色圖像為灰度圖像:
?
cvCvtColor(cimg,gimg,CV_BGR2GRAY); // cimg -> gimg
使用OpenCV轉換函數:?
for(i=0;i<cimg->height;i++) for(j=0;j<cimg->width;j++)
直接轉換:
?? gimgA[i][j]= (uchar)(cimgA[i][j].b*0.114 +
??????????????????????? cimgA[i][j].g*0.587 +
??????????????????????? cimgA[i][j].r*0.299);?
- 顏色空間轉換:
?
cvCvtColor(src,dst,code); // src -> dst
?? code???? = CV_<X>2<Y>
?? <X>/<Y> = RGB, BGR, GRAY, HSV, YCrCb, XYZ, Lab, Luv, HLS
e.g.: CV_BGR2GRAY, CV_BGR2HSV, CV_BGR2Lab?
?
繪圖命令
?
- 畫長方體:// 用寬度為1的紅線在(100,100)與(200,200)之間畫一長方體
cvRectangle(img, cvPoint(100,100), cvPoint(200,200), cvScalar(255,0,0), 1);?
- 畫圓:// 在(100,100)處畫一半徑為20的圓,使用寬度為1的綠線
cvCircle(img, cvPoint(100,100), 20, cvScalar(0,255,0), 1);?
- 畫線段:// 在(100,100)與(200,200)之間畫綠色線段,寬度為1
cvLine(img, cvPoint(100,100), cvPoint(200,200), cvScalar(0,255,0), 1);?
- 畫一組線段:CvPoint?? curve1[]={10,10,?? 10,100,?? 100,100,?? 100,10};
CvPoint?? curve2[]={30,30,?? 30,130,?? 130,130,?? 130,30,?? 150,10};
CvPoint* curveArr[2]={curve1, curve2};
int?????? nCurvePts[2]={4,5};
int?????? nCurves=2;
int?????? isCurveClosed=1;
int?????? lineWidth=1;
cvPolyLine(img,curveArr,nCurvePts,nCurves,isCurveClosed,cvScalar(0,255,255),lineWidth);?
- 畫內填充色的多邊形:cvFillPoly(img,curveArr,nCurvePts,nCurves,cvScalar(0,255,255));
?
- 添加文本:CvFont font;
double hScale=1.0;
double vScale=1.0;
int???? lineWidth=1;
cvInitFont(&font,CV_FONT_HERSHEY_SIMPLEX|CV_FONT_ITALIC, hScale,vScale,0,lineWidth);
cvPutText (img,"My comment",cvPoint(200,400), &font, cvScalar(255,255,0));Other possible fonts:
CV_FONT_HERSHEY_SIMPLEX, CV_FONT_HERSHEY_PLAIN,
CV_FONT_HERSHEY_DUPLEX, CV_FONT_HERSHEY_COMPLEX,
CV_FONT_HERSHEY_TRIPLEX, CV_FONT_HERSHEY_COMPLEX_SMALL,
CV_FONT_HERSHEY_SCRIPT_SIMPLEX, CV_FONT_HERSHEY_SCRIPT_COMPLEX,
總結
以上是生活随笔為你收集整理的OpenCV分配与释放图像空间的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Netcdf
- 下一篇: OpenCV像素点处理