2013-03-25 3 views
1

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

This answer предлагает использовать значение яркости или Y в формате YUV. Поэтому я следую this answer, чтобы получить доступ к пикселю в образовании из изображения 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 

ответ

1

Причина для вывода журнала является то, что ваши пиксельными значения имеют типа uint8_t, который будет интерпретирован как unsigned char (на прошивке, по крайней мере) при попытке вывести его на консоль. Таким образом, выход журнала является символом, представленным этим значением пикселя. Для вывода соответствующего числового значения, отлитый значение к 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, но будет более эффективным.

+0

Извините за мою ошибку, я исправил. Спасибо вам за ваши предложения. Еще одна вещь, вы имеете представление о подходящем количестве пикселей, которые будут вычисляться в строках 'for (int i = 0; i Protocole

+0

Боюсь, я не совсем понимаю, что вы здесь просите. И почему вы каждый раз увеличиваете на 50? – Aurelius

+0

Я имею в виду, что вычисление на каждом пикселе вызывает плохую производительность, поэтому я попытался пробовать только 1 пиксель на 50 пикселей, чтобы рассчитать, чтобы не повлиять на производительность, но все еще имеет достаточную точность. Я ищу это оптимальное число. – Protocole

0

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

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