rem*_*em7 3 c++ arrays performance opencv iplimage
我需要一些C++ /指针帮助.当我创建一个RGB IplImage并且我想访问i时,我使用以下C++类:http://www.cs.iit.edu/~agam/cs512/lect-notes/opencv-intro/opencv- intro.html
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;
Run Code Online (Sandbox Code Playgroud)
我一直在使用CUDA,所以有时我必须将所有数据放入一个数组中,我喜欢将每个通道保存在自己的数组中,这样看起来更容易处理数据.所以我通常会这样做:
IplImage *image = cvLoadImage("whatever.tif");
RgbImageFloat img(image);
for(int i = 0; i < exrIn->height; i++)
{
for(int j = 0; j < exrIn->width; j++)
{
hostr[j*data->height+i] = img[i][j].r;
hostg[j*data->height+i] = img[i][j].g;
hostb[j*data->height+i] = img[i][j].b;
}
}
Run Code Online (Sandbox Code Playgroud)
然后我会将我的数据复制到设备上,用它做一些事情,把它拿回主机然后再循环,然后通过数组将数据分配回IplImage并保存我的结果.
看起来我已经循环到很多,必须有一个更快的方法用指针做这个,但我迷路了,必须有一个更有效的方法来做到这一点.有没有办法可以简单地为每个频道使用指针?我尝试过这样的事情,但它不起作用:
float *hostr = &img[0][0].r
float *hostg = &img[0][0].b
float *hostb = &img[0][0].g
Run Code Online (Sandbox Code Playgroud)
有什么建议?谢谢!
编辑:谢谢大家的回答.也许我对自己的问题不太清楚.我熟悉如何访问频道及其数据.我感兴趣的是提高将数据从IplImage完全复制到标准阵列的性能和效率,更多的是csl到目前为止所说的.我看到的问题是IplImage中的数据排列方式是"rgbrgbrgbrgb".
首先,如果你对C++感到满意,你应该考虑使用OpenCV 2.0,它不使用图像和矩阵(IplImage*和CvMat*)的不同数据类型,并使用一个结构(Mat)来处理它们.除了自动内存管理和一大堆有用的例程来处理频道等,以及一些MATLAB特色的,它使用起来真的很有趣.
对于您的特定问题,您可以访问IplImage*with 的频道Mat,如下所示:
IplImage *image = cvLoadImage("lena.bmp");
Mat Lena(image);
vector<Mat> Channels;
split(Lena,Channels);
namedWindow("LR",CV_WINDOW_AUTOSIZE);
imshow("LR",Channels[0]);
waitKey();
Run Code Online (Sandbox Code Playgroud)
现在你有了每个频道的副本vector Channels.
如果你不希望使用OpenCV2.0并提取通道,请注意以下几点.OpenCV以下列方式订购多通道图像:
x(1,1,1) x(1,1,2) x(1,1,3) x(1,2,1) x(1,2,2) x(1,2,3) ...
哪里 x(i,j,k) = an element in row i of column j in channel k
此外,OpenCV的垫它的图像..所以不要忘记跳行与widthStep占这些填充空白.按照csl所说的,在外部循环中增加行指针(使用widthStep)并增加此指针以访问行中的元素.
注意:
既然您现在使用的是2.0,那么您可以绕过IplImage*它Mat Lena = imread("Lena.bmp");.