Я хочу загрузить изображение в opencv и разделить изображение на каналы (RGB), и я хочу увеличить любой из цветов и получить соответствующее выходное изображение. Есть ли самый простой способ решить эту проблему?
Получите пиксели RGB из входного изображения и восстановите выходное изображение в opencv
Ответы (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);
}
Код не проверял, надеюсь поможет.
@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] << " ";
}
}
С интерфейсом 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;
}
Другой вариант — вручную перебрать пиксели изображения и работать с интересующим вас каналом. Это даст вам возможность управлять каждым каналом по отдельности или группой.
Следующий код использует интерфейс 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.