Зачастую, алгоритмы компьютерного зрения работают с изображениями в градациях серого, но человек лучше воспринимает цветные изображения.
Значит, чтобы показать человеку картинку в градациях серого — её нужно раскрасить. Но как это сделать?
Возможно 3 варианта:
вручную, автоматически и в зависимости от заданных пределов.
Вручную — неинтересно.
Рассмотрим раскраску в заданных пределах.
Тут всё просто — нужно просто соотнести значению величины яркости картинки в градациях серого заданное цветовое значение.
Т.к. картинка в градациях серого имеет тип CV_8UC1 (8-битный, беззнакоый, 1-канальный)
то нам нужно соответствие всего для 255 значений.
Я же поступлю проще — возьму картинку цветовой температуры и использую её в качестве базы значений :)
Тут всё просто:
как видим цветовое поле начинается приблизительно с 20 и заканчивается на 760-м пикселе.
Т.о. на мнужно пробежаться по всем «серым пикселям» и пересчитать их значение в диапазон от 20 до 760.
т.к.
gray -> 255
rgb -> 740
, то rgb = gray*740/255 + 20
код:
//
// раскрашивание картинки в градациях серого
//
// http://robocraft.ru
//
#include <cv.h>
#include <highgui.h>
#include <stdio.h>
#include <stdlib.h>
#define CV_PIXEL(type,img,x,y) (((type*)(img->imageData+y*img->widthStep))+x*img->nChannels)
int main(int argc, char* argv[])
{
IplImage *image = 0, *base = 0, *gray = 0, *dst = 0;
// имя картинки задаётся первым параметром
char* filename = argc >= 2 ? argv[1] : "Image0.jpg";
char* base_filename = argc >= 3 ? argv[2] : "800px-Black-body-in-mireds-reversed.png";
// загружаем картинку
image = cvLoadImage(filename);
// загружаем базу цветов
base = cvLoadImage(base_filename);
printf("[i] image: %s \n", filename);
printf("[i] base: %s \n", base_filename);
assert( image && base );
// покажем
cvNamedWindow("image");
cvShowImage("image", image);
cvNamedWindow("base");
cvShowImage("base", base);
// для хранения картинки в градациях серого
gray = cvCreateImage(cvGetSize(image), IPL_DEPTH_8U, 1);
// конвертируем изображение в градации серого
cvConvertImage(image, gray, CV_BGR2GRAY);
// клонируем картинку (для отображения результата)
dst = cvCloneImage(image);
// обнуляем
cvZero(dst);
cvNamedWindow("gray");
cvShowImage("gray", gray);
// параметры палитры цветовой базы
// цвет:
// x 20-760 y 50
// 255 -> 740
int bx = 0;
int by = 50;
// пробегаемся по всем пикселям изображения
for( int y=0; y<gray->height; y++ ) {
uchar* ptr = (uchar*)(gray->imageData + y * gray->widthStep);
for( int x=0; x<gray->width; x++ ) {
// определяем смещение в базовом файле
bx = (int)(ptr[x]*740./255.+20);
// переносим цвет
CV_PIXEL(uchar, dst, x, y)[0] = CV_PIXEL(uchar, base, bx, by)[0];
CV_PIXEL(uchar, dst, x, y)[1] = CV_PIXEL(uchar, base, bx, by)[1];
CV_PIXEL(uchar, dst, x, y)[2] = CV_PIXEL(uchar, base, bx, by)[2];
}
}
// покажем результат
cvNamedWindow("color");
cvShowImage("color", dst);
// ждём нажатия клавиши
cvWaitKey(0);
// освобождаем ресурсы
cvReleaseImage(&image);
cvReleaseImage(&base);
cvReleaseImage(&gray);
cvReleaseImage(&dst);
// удаляем окна
cvDestroyAllWindows();
return 0;
}
Комментарии (3)
RSS свернуть / развернутьdeek
noonv
red21
Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.