Daiver
Daiver

Reputation: 1508

Copying two images pixel by pixel

I am trying to work with each pixel from depth map. (I am implementing image segmentation.) I don't know how to work with pixels from image with depth higher than 1.

This sample code copies depth map to another cv::Mat pixel by pixel. It works fine, if I normalize it (depth of normalized image = 1). But it doesn't work with depth = 3, because .at<uchar> is wrong operation for this depth.

cv::Mat res; 
cv::StereoBM bm(CV_STEREO_BM_NORMALIZED_RESPONSE);
bm(left, right, res);
std::cout<<"type "<<res.type()<<" depth "<<res.depth()<<" channels "<<res.channels()<<"\n";// type 3 depth 3 channels 1
cv::Mat tmp = cv::Mat::zeros(res.rows, res.cols, res.type());
for(int i = 0; i < res.rows; i++)
{
    for(int j = 0; j < res.cols; j++)
        {
                tmp.at<uchar>(i, j) = res.at<uchar>(i, j);
                //std::cout << (int)res.at<uchar>(i, j) << " ";
    }
    //std::cout << std::endl;
}
cv::imshow("tmp", normalize(tmp));
cv::imshow("res", normalize(res));

normilize function

cv::Mat normalize(cv::Mat const &depth_map)
{
    double min;
    double max;
    cv::minMaxIdx(depth_map, &min, &max);
    cv::Mat adjMap;
    cv::convertScaleAbs(depth_map, adjMap, 255 / max);
    return adjMap;
}

screenshot

left image - tmp, right image - res

How can I get the pixel from image with depth equal to 3?

Upvotes: 3

Views: 3097

Answers (2)

morynicz
morynicz

Reputation: 2342

Mat::depth() returns value equal to a constant symbolising bit depth of the image. If You get depth equal to for example CV_32F, to get to the pixels You would need to use float instead of uchar.

CV_8S -> char

CV_8U -> uchar

CV_16U -> unsigned int

CV_16S -> int

CV_32F -> float

CV_64F -> double

Mat::channels() tells You how many values of that type are assigned to a coordinate. These multiple values can be extracted as cv::Vec. So if You have a two channel Mat with depth CV_8U, instead using Mat.at<uchar> You would need to go with Mat.at<Vec2b>, or Mat.at<Vec2f> for CV_32F one.

Upvotes: 3

Barshan Das
Barshan Das

Reputation: 3767

When your images are of depth 3, do this for copying pixel by pixel:

tmp.at<Vec3b>(i,j) = res.at<Vec3b>(i,j);

However, if you are copying the whole image , I do not understand the point of copying each pixel individually, unless you want to do different processing with different pixels.

You can just copy the whole image res to tmp by this:

res.copyTo(tmp);

Upvotes: 3

Related Questions