Как получить яркость изображения Mat из opencv?

Я делаю обработку изображений на iOS с использованием OpenCV в C ++. Иногда окружающего света недостаточно, и изображение не может быть обработано должным образом. Я не нашел подходящего способа обнаружения окружающего света, поэтому попытался определить яркость изображения.

Этот ответ предлагает использовать значение яркости или Y в формате YUV. Так что я следую этот ответ получить доступ к пикселю в формировании из изображения Mat после преобразования изображения в формат YUV.

- (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

Решение

Причиной вывода журнала является то, что значения ваших пикселей имеют тип 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);

Который выполняет то же преобразование цветов, что и Y-канал YUV, но будет более эффективным.

1

Другие решения

Вот как вы можете сделать это довольно просто, у меня работает!

Также размещено здесь на 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);
2

По вопросам рекламы [email protected]