Вырезка части кода OpenCV для вставки в свой проект / OpenCV / Recog.ru - Распознавание образов для программистов


Вырезка части кода OpenCV для вставки в свой проект

Поскольку лицензией OpenCV является BSD, то мы можем делать с ней все, что захотим. Например, вырезать из неё какие-то части, чтобы вставлять в свой проект. Конечно, кто-то пытается сделать собственные библиотеки (этого не избежал и я – библиотека ImagePak), это помогает разобраться в предмете, но зачем изобретать велосипед и многие функции, которые на высоком уровне качества и быстродействия реализованы в свободно распространяемой библиотеке. Поставим задачу: необходимо использовать OpenCV-шные функции по переводу изображения в монохромное в своем проекте для Windows. На самом деле наверняка понадобится значительно больше, но не в этом вопрос. Я буду использовать версию 2.2 (просто лень ставить новую). Нам понадобятся поддержка модулей core и imgproc. Не долго думая, создаем папку opencv_ и копируем туда полностью эти модули. Создаем обычный консольный проект в VisualStudio и подключаем туда все файлы из этих модулей. Создаем main.cpp, в котором кроме функции main() ничего нет. Перед тем как пытаться скомпилировать перепишем пути include в файлах precomp.hpp обоих модулей и в других модулях, где происходит обращение к *.h файлам, чтобы мы уж точно с нашими файлами работали. Например, следующим образом:

#include "opencv_/modules/imgproc/include/opencv2/imgproc/imgproc.hpp"
#include "opencv_/modules/imgproc/include/opencv2/imgproc/imgproc_c.h"
#include "opencv_/modules/core/include/opencv2/core/internal.hpp"

Прописываем в tools->options путь до места, где находится opencv_ и компилируем. Должна вылезти следующая ошибка:

1>------ Build started: Project: testopencv, Configuration: Debug Win32 — 1>Compiling…
1>lapack.cpp
1>e:\vidikon\opencv_\modules\core\src\lapack.cpp(51): fatal error C1083: Cannot open include file: 'clapack.h': No such file or directory
1>Build log was saved at «file://e:\vidikon\testopencv\Debug\BuildLog.htm»
1>testopencv — 1 error(s), 0 warning(s)
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

Поскольку идет ссылка на clapack.h файл в модуле, который мы не подключили. Комментируем его. Появляются ошибки следующего плана:

1>persistence.obj: error LNK2019: unresolved external symbol _gzputs referenced in function «void __cdecl icvPuts(struct CvFileStorage *,char const *)» (?icvPuts@@YAXPAUCvFileStorage@@PBD@Z)
1>persistence.obj: error LNK2019: unresolved external symbol _gzclose referenced in function «void __cdecl icvClose(struct CvFileStorage *)» (?icvClose@@YAXPAUCvFileStorage@@@Z)
1>persistence.obj: error LNK2019: unresolved external symbol _gzopen referenced in function _cvOpenFileStorage

Ставим заглушки (пустоту) на все функции, которых нет при линковке. Понятно дело, что это неправильно, но очень уж хочется, чтобы быстрее заработало. После этого все компилируется. Проверяем работоспособность, модифицировав файл main.cpp следующим образом:
#include "opencv_/modules/core/include/opencv2/core/core_c.h"
#include "opencv_/modules/imgproc/include/opencv2/imgproc/imgproc_c.h"
#include <stdio.h>
#include <windows.h>

int main()
{
	// Загружаем Bitmap - BMP файл
	long s=10000000;
	unsigned char* out_bitmap=new unsigned char [s];
	FILE *f;
	f=fopen("out.bmp","rb");	
	if (f!=NULL)
	{
		long i=0;
		do{
			out_bitmap[i]=fgetc(f);
			i++;
		}while(!feof(f));
		fclose(f);

		// Переводим Bitmap в Image (извиняюсь что коряво - делал очень быстро)
		DWORD offset=0;
		DWORD x=0,y=0;
		WORD Bit=0;
		DWORD a,Size=0;
		int pointer=10;
		memcpy(&offset,&out_bitmap[pointer],4);pointer+=8;
		memcpy(&x,&out_bitmap[pointer],4);pointer+=4;
		memcpy(&y,&out_bitmap[pointer],4);pointer+=6;
		memcpy(&Bit,&out_bitmap[pointer],2);pointer+=2;

		IplImage* img = 0;  

		if (Bit!=24) return 0;
		memcpy(&a,&out_bitmap[pointer],4);pointer+=4;
		if (a!=0) return 0;
		img=cvCreateImage(cvSize(x,y),8,3);		
		uchar* ptr = (uchar*) (img->imageData);
		memcpy(ptr,&out_bitmap[offset],img->widthStep*img->height-10000); 
		// Делаем для теста перевод в монохромное
		IplImage* Gray=cvCreateImage(cvSize(x,y),8,1);
		cvCvtColor(img, Gray, CV_RGB2GRAY );
		cvThreshold( Gray, Gray, 128, 255, CV_THRESH_BINARY );

		//Обратно в 24 бит
		cvCvtColor(Gray,img, CV_GRAY2RGB );
		memcpy(&out_bitmap[offset],ptr,img->widthStep*img->height);

		cvReleaseImage(&img);
		cvReleaseImage(&Gray);

		//Ну а теперь сохраняем в выходной файл
		f=fopen("out2.bmp","wb");	
		fwrite(out_bitmap,1,i,f);
		fclose(f);
	}	
	delete out_bitmap;

	return 0;
}


Вкратце смысл этого файла. Поскольку у нас нет функций загрузки изображения, то читается 24 битный bmp файл целиком в память, а из него вытаскиваются необходимые параметры и изображение. Создается 24 битное изображение img, которое преобразуется в градации серого, выполняется перевод обратно в 24 бит и сохранение в файл. Тестируем – все работает, см 2 рисунка (они правда в JPEG, но реально были в BMP:

До:


После:


В дальнейшем, конечно необходимо выкинуть все неиспользуемые функции, поскольку иначе размер файла может составлять порядка 4MB. В остальном, если по тексту где-то неточности, прошу не обижаться – писал очень быстро.
  • 0
  • 09 марта 2012, 13:32
  • vidikon

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

RSS свернуть / развернуть

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