Получите пиксели RGB из входного изображения и восстановите выходное изображение в opencv

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


person Ragavan    schedule 29.07.2011    source источник


Ответы (4)


Ну, чтобы добавить любой скаляр к изображению RGB, вы можете использовать cvAddS (srcImage, scalarToAdd, dstImage). Вот пример:

int main(int argc, char** argv)

{
// Create a named window with the name of the file.
cvNamedWindow( argv[1], 1 );
// Load the image from the given file name.
IplImage* img = cvLoadImage( argv[1] );
//Make a scalar to add 30 to Blue Color and 20 to Red (BGR format)
CvScalar colorAdd = cvScalar(30.0, 0, 20.0);
cvAddS(img, colorAdd, img);
// Show the image in the named window
cvShowImage( argv[1], img );
// Idle until the user hits the “Esc” key.
while( 1 ) {
if( cvWaitKey( 100 ) == 27 ) break;
}
cvDestroyWindow( argv[1] );
cvReleaseImage( &img );
exit(0);
}

Код не проверял, надеюсь поможет.

person Adrian    schedule 29.07.2011

@karlphillip: Как правило, лучшее решение для изображений RGB — обрабатывает любые отступы в концах строк, а также прекрасно распараллеливается с OMP!

for (int i=0; i < height;i++) 
{
    unsigned char *pRow = pRGBImg->ptr(i);
    for (int j=0; j < width;j+=bpp) 
    // For educational puporses, here is how to print each R G B channel:
      std::cout << std::dec << "R:" << (int) pRow->imageData[j] <<  
                          " G:" << (int) pRow->imageData[j+1] <<  
                          " B:" << (int) pRow->imageData[j+2] << " "; 
    }
}
person Martin Beckett    schedule 29.07.2011

С интерфейсом OpenCV C++ вы можете просто добавить скаляр к изображению с помощью перегруженных арифметических операторов.

int main(int argc, const char * argv[]) {
    cv::Mat image;
    // read an image
    if (argc < 2)
        return 2;

    image = cv::imread(argv[1]);

    if (!image.data) {
        std::cout << "Image file not found\n";
        return 1;
    }

    cv::Mat image2 = image.clone(); // Make a deep copy of the image
    image2 += cv::Scalar(30,0,20); // Add 30 to blue, 20 to red

    cv::namedWindow("original");
    cv::imshow("original", image);

    cv::namedWindow("addcolors");
    cv::imshow("addcolors", image2);

    cv::waitKey(0);
    return 0;
}
person SSteve    schedule 29.07.2011

Другой вариант — вручную перебрать пиксели изображения и работать с интересующим вас каналом. Это даст вам возможность управлять каждым каналом по отдельности или группой.

Следующий код использует интерфейс C OpenCV:

IplImage* pRGBImg = cvLoadImage("test.png", CV_LOAD_IMAGE_UNCHANGED); 
int width = pRGBImg->width; 
int height = pRGBImg->height;
int bpp = pRGBImg->nChannels; 
for (int i=0; i < width*height*bpp; i+=bpp) 
{
  // For educational puporses, here is how to print each R G B channel:
  std::cout << std::dec << "R:" << (int) pRGBImg->imageData[i] <<  
                          " G:" << (int) pRGBImg->imageData[i+1] <<  
                          " B:" << (int) pRGBImg->imageData[i+2] << " "; 
}

Однако, если вы хотите добавить фиксированное значение для определенного канала, вы можете проверить ответ @Popovici.

person karlphillip    schedule 29.07.2011