Определение неправомерной вставки дополнительных кадров в видеопоток / Прикладные вопросы распознавания образов / Recog.ru - Распознавание образов для программистов


Определение неправомерной вставки дополнительных кадров в видеопоток

Предположим, вы разрабатываете какую-нибудь технологию обработки видео информации, поступающей с видеокамеры в реальном времени. Технология готова, но как защитить ее? Вы хотите, чтобы пользователь мог выбрать варианты покупки вашего SDK для одной камеры, двух, трех и т.д. Конечно, нет проблем, если взаимодействие с видео вы встраиваете в SDK, но если такой возможности нет? В таком случае можно анализировать последовательность кадров, чтобы определить, принадлежат ли кадры текущему видеопотоку или нет. Данную возможность можно реализовать, используя реализованную в OpenCV технологию отличий. При реализации примера будем иметь в виду, что камера неподвижна и однонаправлена.
Поскольку неизвестно, как будет подделываться видеопоток (после каждого кадра или после последовательности кадров), то нельзя заниматься сравнением только последовательных кадров. Но можно чередовать сравнения, например один кадр – сравниваем с предыдущем, второй – с 5 кадром перед этим и т.п. После нахождения отличий можно посчитать процент измененного изображения и суммировать результат в единицу времени.
Необходимо где-то хранить предыдущие кадры. Для этого реализуем циклический список из N + 1 элементов, где N – характеризует возраст самого старого кадра. Список организуем так: IplImage* ImageList[LIST_COMPARE];. Естественно, что первоначально необходимо проинициализировать, создать изображения по размеру кадра или (что наиболее вероятно, поскольку данная функция будет работать медленно, использую уменьшенное изображение при помощи cvResize). При снятии нового изображения, оно будет записываться в текущий элемент списка, а указатель будет смещаться. Когда дойдем до значения LIST_COMPARE, то указатель перемещается на начало. Пока список изображений не заполнится, анализ на подмену не производится.
Выбор номера кадра, с которым сравнивается текущий, может осуществляться случайным образом или по какой-то специальной формуле. В примере выбор осуществлялся по следующему выражению: Max_(1,(1<<(pointer%4)-1)), где pointer – номер текущего кадра в списке.
Затем осуществляется детектирование отличий с помощью cvUpdateBGStatModel. Ну а потом в цикле перебираются пиксели для подсчета количества отличий – белых пикселей, после чего вычисляется процент различий. Если отличий более 75%, то этот кадр скорее всего другой. Но скорее всего. Поскольку вдруг произошло какое-то движение в кадре масштабное, включение / выключение света. Но этого часто не может быть, поэтому можно в течении некоторого времени суммировать показатель, который будет сигнализировать об подмене. В данном примере используется буфер размером 32 элемента. Текст программы вы можете посмотреть ниже или скачать http://vidikon.com/sources/ProtectionVideo.cpp.
#include <opencv2/video/background_segm.hpp>
#include <opencv2/core/core_c.h>
#include <opencv2/highgui/highgui_c.h>
#include <opencv2/imgproc/imgproc_c.h>
#include <math.h>

#define Max_( a, b ) ( (a) > (b) ? (a) : (b) )

#define LIST_COMPARE			9
#define LIST_COMPARE_SAVE		32

IplImage* ImageList[LIST_COMPARE];
int buffer[LIST_COMPARE_SAVE];

void CompareImage(IplImage* Image);

void InitImage(IplImage* Image)
{
	for(int i=0;i<LIST_COMPARE;i++)
		ImageList[i]=cvCreateImage(cvSize(Image->width,Image->height),8,3);
}

void ReleaseImage()
{
	for(int i=0;i<LIST_COMPARE;i++)
		cvReleaseImage(&ImageList[i]);
}

int main()
{
	CvCapture*      cap = NULL; 
	cap = cvCaptureFromFile("record1.avi"); 
	CvCapture*      cap2 = NULL; 
	cap2 = cvCaptureFromFile("record2.avi"); 
	cvNamedWindow( "Demo", 1 );  
	bool first=0;
	int p=0;
	IplImage* image=0;
	do{
		if (p%2==0) image = cvQueryFrame( cap);
		else image = cvQueryFrame( cap2);
		if( !image ) break;
		if (!first)
		{
			first=1;
			InitImage(image);
		}
		CompareImage(image);
		//cvShowImage("Demo",image);
		if ( cvWaitKey(20)==27) break;
		p++;
		if (p==100) p=0;
	}while(1);
	ReleaseImage();
	cvDestroyWindow("Demo");
	cvReleaseCapture(&cap);
	cvReleaseCapture(&cap2);
	return 0;
}


void CompareImage(IplImage* Image)
{
	static int currentimage = -1;
	static int allimages	= 0;
	static int pointer		= -1;
	currentimage++;	
	pointer++;
	if (currentimage>=LIST_COMPARE) currentimage=0;
	if (pointer>=LIST_COMPARE-1) pointer=0;

	cvCopy(Image,ImageList[currentimage]);	

	if (allimages<LIST_COMPARE-1) 
	{
		allimages++;
		return;
	}

	// Далее отличия фона
	int i,j;
	i=currentimage-Max_(1,(1<<(pointer%4)-1));
	if (i<0) i+=LIST_COMPARE; // Это все для циклического списка

	CvBGStatModel* bg_model = 0;

	bg_model = cvCreateFGDStatModel( Image);
	cvUpdateBGStatModel( ImageList[i], bg_model, -1);
	cvShowImage("Demo",bg_model->foreground);

	// Необходимо посчитать количество отличий
	uchar* ptr = (uchar*) (bg_model->foreground->imageData);

	long all=0;
	for(i=0;i<bg_model->foreground->height;i++)
		for(j=0;j<bg_model->foreground->width;j++)
			if (ptr[j+i*bg_model->foreground->widthStep]==255) all++;


	float k = (float) all/(bg_model->foreground->width*bg_model->foreground->height);

	static int pointer_compare		= -1;
	static int allcompare	= 0;

	pointer_compare++;
	if (pointer_compare>=LIST_COMPARE_SAVE) pointer_compare=0;

	if (k>0.75f) buffer[pointer_compare]=8;
	else{
		if (k>0.5f) buffer[pointer_compare]=4;
		else {
			if (k>0.25f) buffer[pointer_compare]=1;
			else buffer[pointer_compare]=0;
		}
	}
	if (allcompare<LIST_COMPARE_SAVE) 
	{
		allcompare++;
	}
	else
	{
		// Расчет среднего значения
		all=0;
		for(i=0;i<LIST_COMPARE_SAVE;i++)
			all+=buffer[i];		
		printf("%d\n",all);
	}
	//printf("%5.3f\n",k);

	cvReleaseBGStatModel( &bg_model );
}

В тестируемом примере, как вы видите использовалось 2 видеофайла. И собственно при подмене значение показателя all было выше 64, а на том же видеофайле – меньше 16. Таким образом можно было бы выбрать пороговое значение 30 при превышении которого сигнализировать об возможной неправомерной вставке чужих кадров в видеопоток. Функция работает медленно, поэтому с некоторым ухудшением качества изображение можно уменьшить раза так в 4.
  • 0
  • 18 февраля 2012, 14:39
  • vidikon

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

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

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