逐像素复制两个图像

问题描述:

我正在尝试处理深度图中的每个像素. (我正在实现图像分割.)我不知道如何处理深度大于1的图像中的像素.

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.

此示例代码将深度图逐像素复制到另一个cv :: Mat.如果我对其进行归一化(归一化图像的深度= 1),则它可以正常工作.但这不适用于depth = 3,因为.at<uchar>对此深度的操作不正确.

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));

规范化功能

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;
}

左图-tmp,右图-res

left image - tmp, right image - res

如何从深度等于3的图像中获取像素?

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

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() 告诉您有多少个值该类型的对象将分配给一个坐标.可以将这些多个值提取为 cv::Vec .因此,如果您有一个深度为CV_8U的两个通道Mat,而不是使用Mat.at<uchar>,则需要使用Mat.at<Vec2b>Mat.at<Vec2f>表示CV_32F.

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.