OpenCV - Раскрашиваем картинку в градациях серого

Зачастую, алгоритмы компьютерного зрения работают с изображениями в градациях серого, но человек лучше воспринимает цветные изображения.

Значит, чтобы показать человеку картинку в градациях серого — её нужно раскрасить. Но как это сделать?

Возможно 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;
}

скачать иcходник (gray2color.cpp)



Автоматическая ракраска, подразумевает, что база цветовых значений будет генерироваться автоматически.

Ссылки:
Pseudocolor implementation with OpenCV.
en.wikipedia.org/wiki/Color_temperature
  • 0
  • 11 июня 2011, 09:56
  • noonv

Комментарии (3)

RSS свернуть / развернуть
+
0
И вот это вот цветное изображение, что получилось в итоге, человек должен воспринять лучше?
avatar

deek

  • 13 июня 2011, 12:48
+
0
согласен — пример неудачный :)
avatar

noonv

  • 13 июня 2011, 13:05
+
+1
прям тепловизор :)
avatar

red21

  • 23 июня 2011, 13:46

Только зарегистрированные и авторизованные пользователи могут оставлять комментарии.