Ответ 1
- Изображения
-
IPL_DEPTH_64F
илиdouble
будут обрабатывать данные от 0 до 1. - Если вы привыкли к С++, вы должны проверить OpenCV2.0, который имеет несколько классов С++ и, самое главное, один класс, т.е.
Mat
для обработки изображений, матриц и т.д.
Вот простой способ эффективного доступа к элементам изображения:
IplImage* img = cvCreateImage(cvSize(300,300),IPL_DEPTH_64F,1);
for( int y=0; y<img->height; y++ )
{
double* ptr = reinterpret_cast<double*>(img->imageData + y * img->widthStep);
for( int x=0; x<img->width; x++ )
{
ptr[x] = double(255);
}
}
cvNamedWindow("SO");
cvShowImage("SO",img);
cvWaitKey();
cvDestroyAllWindows();
cvReleaseImage(&img);
Поскольку вы работаете с изображением double
, имеет смысл:
- Работайте с указателем
double
, чтобы вы могли легко назначать элементы в строкеptr[x]
- Сделайте арифметику указателя в байтах (
img->imageData + y * img->widthStep
) и передайте ее указателюdouble
Кроме того, это важно, что вы выполняете арифметику указателя в байтах (или uchar
, т.е. unsigned char
), так как OpenCV стремится накладывать строки изображений с дополнительными байтами для эффективности (особенно для double
изображений).
Таким образом, даже если элемент double
равен 8 байтам, и у вас есть, скажем, 300 строк, строка не будет гарантирована на 8 * 300 или 2400 байт, так как OpenCV может пропустить конец.
Следовательно, это не позволяет вам инициализировать указатель на первый элемент изображения, а затем использовать ptr[y*img->height+x]
для доступа к элементам, поскольку каждая строка может содержать более 8*(y*img->height)
байтов.
Это, почему код примера каждый раз вычисляет указатель на каждую строку, используя img->widthStep
, который представляет истинный размер каждой строки в байтах.
OpenCV 2.0
Если вы используете класс Mat
, вы можете сделать то же самое в следующих строках:
cv::Mat img(300,300,CV_64FC1);
for( int y=0; y<img.rows; y++ )
{
double* ptr = reinterpret_cast<double*>(img.data + y * img.step);
for( int x=0; x<img.cols; x++ )
{
ptr[x] = double(255);
}
}
cv::namedWindow("SO");
cv::imshow("SO",img);
cv::waitKey();
где img.step - это расстояние между последовательными строками в байтах
И если вы хотите получить прямой доступ к элементу (медленнее):
img.at<double>(y,x)