2014-10-13 4 views
0

В настоящее время я загружаю изображение лица в мат, устанавливая координаты центральной точки X и Y каждого глаза, создавая круг вокруг каждого из глаз, устанавливая ROI в круги вокруг глаз (используя Rect и установив маску) и опустив красное значение в изображениях глаз.OpenCV: Создайте прозрачную маску?

Моя проблема заключается в объединении исправленного глаза (с опущенным красным цветом) обратно на исходное изображение, потому что исправленные глаза имеют черную маску. Я не уверен, как избавиться от черной маски.

В настоящее время я застрял на немного OpenCV кода, который получил меня к этой точке:

Исходное изображение:

Извлеченные глаз с черной маской:

Исправленный глаз:

Текущий результат отображения моей проблемы:

Это продолжение моего нить здесь: Getting ROI from a Circle/Point

Я понимаю, что вы не можете создать круговую ROI, таким образом, почему я пошли с Rect ROI и черной маской. Нормального Rect недостаточно.

Любые советы очень ценятся! Спасибо.

+1

хех, чувствуя себя немного ответственной за текущую проблему. ;) что если вы * проверяете * изображение с обрезанным рисунком (с маской, чтобы избавиться от частей кожи), но * write_to/correct * cloneRoi (или даже ровно, вам не нужно будет писать его) и использовать для copyTo()? – berak

+0

Эй, @Берак! Ноно, ты мне так помог! Я получаю то, что вы сейчас говорите! Это то, что у меня есть в настоящее время (быстро измененный код): http://i.imgur.com/4CmL2KJ.jpg Я думаю, что он был в небольшой аварии ... ха. Вероятно, используя неправильный глаз, проверьте сейчас. – LKB

+1

Да, я использовал не тот глаз, хе. :) – LKB

ответ

2

можно использовать замаскированную Roi изображение для тестирования пикселей, но писать в свой реальное изображение:


cv::Mat plotImage; 
    int radius = 15; 
    float threshold = 1.8; 

    plotImage = cv::imread("C:/temp/debug.jpg", cv::IMREAD_COLOR); 

    cv::Point leftEye(person.GetLeftEyePoint().X, person.GetLeftEyePoint().Y); 
    cv::Point rightEye(person.GetRightEyePoint().X, person.GetRightEyePoint().Y); 

    //get the Rect containing the circle 
    cv::Rect r(leftEye.x-radius, leftEye.y-radius, radius*2, radius*2); 
    //obtain the image ROI 
    cv::Mat roi(plotImage, r); 
    //make a black mask, same size 
    cv::Mat mask(roi.size(), roi.type(), cv::Scalar::all(0)); 
    //with a white filled circle in it 
    cv::circle(mask, cv::Point(radius, radius), radius, cv::Scalar::all(255), -1); 
    //combine roi & mask 
    cv::Mat croppedEye = roi&mask; 

    //conduct red eye detection/removal on croppedEye 
    int count = 0; 
    for(int y=0;y<croppedEye.rows;y++) 
    { 
      for(int x=0;x<croppedEye.cols;x++) 
      { 
        double b = croppedEye.at<cv::Vec3b>(y, x)[0]; 
        double g = croppedEye.at<cv::Vec3b>(y, x)[1]; 
        double r = croppedEye.at<cv::Vec3b>(y, x)[2]; 

        double redIntensity = r/((g + b)/2); 

        //currently causes issues with non-red-eye images 
        if (redIntensity >= threshold) 
        { 
          double newRedValue = (g + b)/2; 
          cv::Vec3b pixelColor(newRedValue,g,b); 
          // 
          // here's the trick now, just write back to the original image ;) 
          // 
          roi.at<cv::Vec3b>(cv::Point(x,y)) = pixelColor; 
          count++; 
        } 
      } 
    } 

    cv::imwrite("C:\\temp\\test.jpg", plotImage); 

enter image description here

+0

Еще раз спасибо! :) – LKB

+1

удовольствие, было очень весело с ним;) – berak

0

Проверить этот пост. Transparent mask

if (imageMask.at<Vec3b>(xx,yy)[0] < 10) 
// This mean If the color of mask in one channel is < 10 replace the original Image 
           { 
                // Copy to original image on (y,x) places the pixel of xx,yy mask 
    OriginalImage.at<Vec3b>(y,x)[0] = imageMask .at<Vec3b>(xx,yy)[0]; 
    OriginalImage.at<Vec3b>(y,x)[1] = imageMask .at<Vec3b>(xx,yy)[1]; 
    OriginalImage.at<Vec3b>(y,x)[2] = imageMask .at<Vec3b>(xx,yy)[2]; 
           } 
Смежные вопросы