Handling of 3d points for every image's pixel

asked 2018-04-13 10:10:36 -0600

eicoo5Ei gravatar image

updated 2018-04-13 10:34:56 -0600

Hi All,

I'm having a hard time to understand how OpenCV handles matrices of 3d vectors. What I have is a grayscale image and additional 3 floating point images with the same size. The float images represent the x,y,z coordinates of each point in the grayscale image. I want to perform angle calculations on these, e.g. the cosine between each pixel location's vector with the normal (0,0,1).

E.g., when filename_0 contains the x coordinate of the vector for every pixel, filename_1 the y-coordinate, filename_2 the z-coordinate, my code looks like this:

std::vector<cv::Mat> inc;
inc.push_back(imread_geo( argv[1]+string("_0"), CV_32FC1 ));
inc.push_back(imread_geo( argv[1]+string("_1"), CV_32FC1 ));
inc.push_back(imread_geo( argv[1]+string("_2"), CV_32FC1 ));
Mat3f mat_inc;
cv::merge(inc,mat_inc);

What I do is to create a std::vector<cv::mat> matrix and convert it to a 3-channel 2D matrix using cv:merge. But how to use functions for angle calculations on mat_inc?

EDIT:The imread_geo function is adapted from this example: https://docs.opencv.org/3.0-beta/doc/... Loading the images using cv:imread and cv::IMREAD_LOAD_GDAL did not work with my file types (but should not matter here).

Background: the vectors are the Sun direction (incidence angle) for every pixel and I want to calculate the cosine of the incidence angle in the simplest case.

Any help is greatly appreciated! Eicoo

edit retag flag offensive close merge delete

Comments

imread( argv[1]+string("_0"), CV_32FC1 ) -- this won't work. CV_32FC1 is not a valid flag for imread, and only .exr or .hdf support loading/saving float images.

berak gravatar imageberak ( 2018-04-13 10:23:41 -0600 )edit
1

OK sorry this is only pseudo code as I'm loading the images using GDALs library. The code for loading the images as CV32F is working already... I change the lines to imread_geo(...).

eicoo5Ei gravatar imageeicoo5Ei ( 2018-04-13 10:27:29 -0600 )edit

cosine is just the dot product.

Vec3f normal(0,0,1);
Vec3f pixel3d(x,y,z);

float cosine = pixel3d.dot(normal);

unfortunately, opencv does not provide a "bulk" method, for a whole Mat of vectors, so i'm unsure, if you gain anything with merging your coord maps.

berak gravatar imageberak ( 2018-04-13 10:31:58 -0600 )edit
1

Thank you that helped. I also found out that I can do Vec3f sun = mat_inc.at<Vec3f>(i, j); to comfortably assign the three-channel image data (at pixel coordinates i,j) to a 3D float vector.

eicoo5Ei gravatar imageeicoo5Ei ( 2018-04-16 04:14:55 -0600 )edit