如何从opencv获得Mat图像的亮度?

时间:2013-03-25 10:52:22

标签: c++ ios opencv image-processing luminance

我正在使用c ++中的OpenCV在iOS上进行图像处理。有时环境光线不足,无法正确处理图像。我没有找到任何合适的方法来检测环境光,因此试图检测图像的亮度。

This answer建议使用YUV格式的亮度值或Y.因此,在将图像转换为YUV格式后,我按照this answer访问Mat图像中的像素。

- (void)processImage:(Mat&)image
{    
    Mat frame_yuv;
    cvtColor( image, frame_yuv, CV_BGR2YUV );

    uint8_t* pixelPtr = (uint8_t*)frame_yuv.data;
    int cn = frame_yuv.channels();
    for(int i = 0; i < frame_yuv.rows; i+=50)
    {
        for(int j = 0; j < frame_yuv.cols; j += 50)
        {
            Scalar_<uint8_t> yuvPixel;
            yuvPixel.val[0] = pixelPtr[i*frame_yuv.cols*cn + j*cn + 0]; // Y
            yuvPixel.val[1] = pixelPtr[i*frame_yuv.cols*cn + j*cn + 1]; // U
            yuvPixel.val[2] = pixelPtr[i*frame_yuv.cols*cn + j*cn + 2]; // V

            // do something with YUV values...
            std::cout << "Y: " << yuvPixel.val[0] << endl;
            std::cout << "U: " << yuvPixel.val[1] << endl;
            std::cout << "V: " << yuvPixel.val[2] << endl;
        }
    }
}

以下是一些日志行,其中包含一些奇怪的结果,“Y”,“U”或“V”的值在我的理解中不应该这么多。请建议我错过了什么或做错了什么?非常感谢你。

Y: P
U: \204
V: \206
Y: Q
U: \201
V: \207
Y: K
U: \205
V: \211
Y: H
U: \203
V: \210
Y: G
U: \202
V: \210
Y: H
U: \201
V: \210
Y: H
U: \202
V: \211
Y: \326
U: \200
V: \204
Y: \377
U: \200
V: \200
Y: \377
U: \200
V: \200
Y: \377
U: \200
V: \200
Y: \376
U: |
V: \201
Y: \313
U: x
V: \210
Y: \231
U: ~
V: \204
Y: \214
U: ~
V: \204
Y: \205
U: |
V: \204
Y: \221
U: 
V: \202

2 个答案:

答案 0 :(得分:3)

以下是你如何做到这一点,非常适合我!

此处也在PasteBin上发布:https://pastebin.com/tA1R8Qtm

// -----------------------------------------------------
// ---------- FIND AVG LUMINENCE OF FRAME --------------
// -----------------------------------------------------

// Assuming you have a cv::Mat to start with called "input_mat"
cv::Mat grayMat; 
cv::cvtColor(input_mat, grayMat, CV_BGR2GRAY);

int Totalintensity = 0;
for (int i=0; i < grayMat.rows; ++i){
    for (int j=0; j < grayMat.cols; ++j){
        Totalintensity += (int)grayMat.at<uchar>(i, j);
    }
}

// Find avg lum of frame
float avgLum = 0;
avgLum = Totalintensity/(grayMat.rows * grayMat.cols);

答案 1 :(得分:1)

您的日志输出的原因是您的像素值是uint8_t类型,当您尝试将其输出到控制台时,它将被解释为unsigned char(至少在iOS上)。因此,日志输出是该像素值表示的字符。要输出相应的数值,请将值转换为int,如下所示:

std::cout << "Y: " << (int)yuvPixel.val[0] << std::endl;
std::cout << "U: " << (int)yuvPixel.val[1] << std::endl;
std::cout << "V: " << (int)yuvPixel.val[2] << std::endl;

此外,您发布的代码输出了相同的元素三次,bgrPixel未定义。我也纠正了这个片段中的错误。

如果您只对亮度信息感兴趣,可以改为调用

cv::cvtColor(image, frame_yuv, CV_BGR2GRAY);

与YUV的Y通道进行相同的颜色转换,但效率会更高。