C ++编程2中的问题 [英] problem in c++ programing 2

查看:52
本文介绍了C ++编程2中的问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

再见一次
我正在处理一个图像处理项目.我可以理解matlab程序,但是C ++存在一些问题.
我找到了一个用于前景检测的C ++程序,但是我不理解其中的某些指令,例如:

Hi again
I am working on a image processing project.I can understand matlab program but i have some problem with C++.
I found a C++ program for foreground detection.But i don''t understand some of instruction in it.for example:

bgModel[index].mode[m].r[i] = curTextureHist[index].r[i];


.mode[m]是什么意思.
一帧就可以写吗?
我看不到增加framenum的说明.
使用此代码:


whats mean of .mode[m].
and is it writting for one frame?
i don''t see the instruction for increasing framenum.
at this code:

unsigned int frameNum = 0;
axisCam->GetImage(image.Ptr(), frameNum);
LBP(image, texture);
Histogram(texture, curTextureHist);
for(int y = REGION_R+TEXTURE_R; y < height-REGION_R-TEXTURE_R; ++y)
{
    for(int x = REGION_R+TEXTURE_R; x < width-REGION_R-TEXTURE_R; ++x)
    {
        int index = x+y*width;

        for(int m = 0; m < NUM_MODES; ++m)
        {
            for(int i = 0; i < NUM_BINS; ++i)
            {
                bgModel[index].mode[m].r[i] = curTextureHist[index].r[i];
                bgModel[index].mode[m].g[i] = curTextureHist[index].g[i];
                bgModel[index].mode[m].b[i] = curTextureHist[index].b[i];
            }
        }
    }
}



这是程序.



and this is the program.

///////////////////////////////////////////////////////////////////////////////
// Texture-based background subtraction based on the paper:
//
// "A texture-based method for modeling the background and
//  detecting moving objects"
// 		by M. Heikkila and M. Pietikainen (2005)
//
// The method has been extended to work with colour images. Strict conditional
// updating is used. Only a single mode is maintained for each pixel.
//
// 
//
// Hit "ESC" to exit the program. You must set AXIS_IP_ADDR to the IP 
// address of your Axis 206 camera.
//
// By Donovan Parks (donovan.parks@gmail.com)
//    January, 2008
//
///////////////////////////////////////////////////////////////////////////////

#include "AxisCamera.h"

#include <fstream>
#include <assert.h>
#include <iostream>

#include <cv.h>
#include <cxcore.h>
#include <highgui.h>
#include <pthread.h>

#include "memJpegDecoder.h"
#include "ConnectedComponents.h"


using namespace std;

// IP address of Axis 206 camera
#define AXIS_IP_ADDR "192.168.2.5"

// Global variable that should be set to true in order to cleanly exit program
bool gTerminate = false;

// Worker threads.
void *readVideo( void *ptr );
void *displayVideo( void *ptr );
void *textureBGS( void *ptr );

int main(int argc, const char* argv[])
{
	AxisSettings axisSettings;
	axisSettings.width = 160;
	axisSettings.height = 120;
	axisSettings.compression = 30;
	axisSettings.requestedFPS = 30;
	axisSettings.colorLevel = 0;		// DP: doesn't work??
	axisSettings.rotation = 0;			
	axisSettings.showClock = 0;
	axisSettings.showDate = 0;
	axisSettings.showText = 0;
	
	// initialize Axis camera
	AxisCamera* axisCam = new AxisCamera(axisSettings, AXIS_IP_ADDR);
	
	// create thread to read video
	pthread_t readVideoThread;
	int ret = pthread_create( &readVideoThread, NULL, readVideo, (void*) axisCam);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}
	
	// create thread to display video
	pthread_t displayVideoThread;
	ret = pthread_create( &displayVideoThread, NULL, displayVideo, (void*) axisCam);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}
	
	// create thread to display results of foreground segmentation
	pthread_t textureThread;
	ret = pthread_create( &textureThread, NULL, textureBGS, (void*) axisCam);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}

	// wait till mediod thread is complete before exiting main
	ret = pthread_join(textureThread, NULL);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}
	
	// wait till display video thread is complete before exiting main
	ret = pthread_join(displayVideoThread, NULL);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}
	
	// wait till read video thread is complete before exiting main
	ret = pthread_join(readVideoThread, NULL);
	if(ret != 0)
	{
		perror("Error");
		exit(ret);
	}
	
	delete axisCam;
	
	exit(0);
}

void *readVideo( void *ptr )
{
	AxisCamera* axisCam = (AxisCamera *) ptr;
	
	// continue to acquire images until the user wishes to terminate
	while(!gTerminate)
	{
		axisCam->AcquireImages();
	}
	
	return 0;
}

void *displayVideo( void *ptr )
{
	AxisCamera* axisCam = (AxisCamera *) ptr;
	
	IplImage* image = cvCreateImage(cvSize(axisCam->Width(), axisCam->Height()), 8, 3);
		
	cvNamedWindow("Video Frame",1);
	
	unsigned int frameNum = 0;
	while(!gTerminate)
	{
		axisCam->GetImage(image, frameNum);
		
		cvShowImage("Video Frame",image);
		
		// sleep for 10ms or until user presses a key
		int key = cvWaitKey(10);
		
		// check if user is finished (i.e., ESC is pressed)
		if((key&0xFF) == 27)	
		{
			gTerminate = true;
		}
	}
	
	cvReleaseImage(&image);	
	cvDestroyWindow("Video Frame");
	
	return 0;
}

// --- Texture-based BGS ----------------------------------------------------------------

const int REGION_R = 5;			// Note: the code currently assumes this value is <= 7
const int TEXTURE_POINTS = 6;	// Note: the code currently assumes this value is 6
const int TEXTURE_R = 2;		// Note: the code currently assumes this value is 2
const int NUM_BINS = 64;		// 2^TEXTURE_POINTS
const int HYSTERSIS = 3;
const float ALPHA = 0.01f;
const float THRESHOLD = 0.7*(REGION_R+REGION_R+1)*(REGION_R+REGION_R+1)*NUM_CHANNELS;
const int NUM_MODES = 1;		// The paper describes how multiple modes can be maintained,
								// but this implementation does not fully support more than one
struct TextureHistogram
{
	unsigned char r[NUM_BINS];	// histogram for red channel
	unsigned char g[NUM_BINS];	// histogram for green channel
	unsigned char b[NUM_BINS];	// histogram for blue channel
};

struct TextureArray
{
	TextureHistogram mode[NUM_MODES];
};

void LBP(RgbImage& image, RgbImage& texture)
{
	for(int y = TEXTURE_R; y < image.Ptr()->height-TEXTURE_R; ++y)
	{
		for(int x = TEXTURE_R; x < image.Ptr()->width-TEXTURE_R; ++x)
		{		
			for(int ch = 0; ch < NUM_CHANNELS; ++ch)
			{
				unsigned char textureCode = 0;
				int centerValue = (int)image(y, x, ch);
	
				// this only works for a texture radius of 2
				if(centerValue - (int)image(y-2, x, ch) + HYSTERSIS >= 0)
					textureCode += 1;
				
				if(centerValue - (int)image(y-1, x-2, ch) + HYSTERSIS >= 0)
					textureCode += 2;
				
				if(centerValue - (int)image(y-1, x+2, ch) + HYSTERSIS >= 0)
					textureCode += 4;
				
				if(centerValue - (int)image(y+1, x-2, ch) + HYSTERSIS >= 0)
					textureCode += 8;
				
				if(centerValue - (int)image(y+1, x+2, ch) + HYSTERSIS >= 0)
					textureCode += 16;
				
				if(centerValue - (int)image(y+2, x, ch) + HYSTERSIS >= 0)
					textureCode += 32;
				
				texture(y,x,ch) = textureCode;
			}
		}
	}
}

void Histogram(RgbImage& texture, TextureHistogram* curTextureHist)
{
	// calculate histogram within a 2*REGION_R square
	for(int y = REGION_R+TEXTURE_R; y < texture.Ptr()->height-REGION_R-TEXTURE_R; ++y)
	{
		for(int x = REGION_R+TEXTURE_R; x < texture.Ptr()->width-REGION_R-TEXTURE_R; ++x)
		{	
			int index = x+y*(texture.Ptr()->width);
			
			// clear histogram
			for(int i = 0; i < NUM_BINS; ++i)
			{
				curTextureHist[index].r[i] = 0;
				curTextureHist[index].g[i] = 0;
				curTextureHist[index].b[i] = 0;
			}
			
			// calculate histogram
			for(int j = -REGION_R; j <= REGION_R; ++j)
			{
				for(int i = -REGION_R; i <= REGION_R; ++i)
				{
					curTextureHist[index].r[texture(y+j,x+i,2)]++;
					curTextureHist[index].g[texture(y+j,x+i,1)]++;
					curTextureHist[index].b[texture(y+j,x+i,0)]++;
				}
			}
		}
	}
}

int ProximityMeasure(TextureHistogram& bgTexture, TextureHistogram& curTextureHist)
{
	int proximity = 0;	
	for(int i = 0; i < NUM_BINS; ++i)
	{
		proximity += min(bgTexture.r[i], curTextureHist.r[i]);
		proximity += min(bgTexture.g[i], curTextureHist.g[i]);
		proximity += min(bgTexture.b[i], curTextureHist.b[i]);
	}
	
	return proximity;	
}

void BgsCompare(TextureArray* bgModel, TextureHistogram* curTextureHist, 
					unsigned char* modeArray, float threshold, BwImage& fgMask)
{
	cvZero(fgMask.Ptr());
	
	for(int y = REGION_R+TEXTURE_R; y < fgMask.Ptr()->height-REGION_R-TEXTURE_R; ++y)
	{
		for(int x = REGION_R+TEXTURE_R; x < fgMask.Ptr()->width-REGION_R-TEXTURE_R; ++x)
		{	
			int index = x+y*(fgMask.Ptr()->width);
		
			// find closest matching texture in background model
			int maxProximity = -1;
			for(int m = 0; m < NUM_MODES; ++m)
			{
				int proximity = ProximityMeasure(bgModel[index].mode[m], curTextureHist[index]);
						
				if(proximity > maxProximity)
				{
					maxProximity = proximity;
					modeArray[index] = m;
				}
			}
			
			if(maxProximity < threshold)
			{
				fgMask(y,x) = 255;
			}
		}
	}
}

void UpdateModel(BwImage& fgMask, TextureArray* bgModel, 
					TextureHistogram* curTextureHist, unsigned char* modeArray)
{
	for(int y = REGION_R+TEXTURE_R; y < fgMask.Ptr()->height-REGION_R-TEXTURE_R; ++y)
	{
		for(int x = REGION_R+TEXTURE_R; x < fgMask.Ptr()->width-REGION_R-TEXTURE_R; ++x)
		{		
			int index = x+y*(fgMask.Ptr()->width);
			
			if(fgMask(x,y) == 0)
			{
				for(int i = 0; i < NUM_BINS; ++i)
				{
					bgModel[index].mode[modeArray[index]].r[i]
				      = (unsigned char)(ALPHA*curTextureHist[index].r[i]
					    + (1-ALPHA)*bgModel[index].mode[modeArray[index]].r[i] + 0.5);
				}
			}				
		}
	}	
}

void *textureBGS( void *ptr )
{
	AxisCamera* axisCam = (AxisCamera *) ptr;
	int width = axisCam->Width();
	int height = axisCam->Height();
	int size = width*height;
	
	// camera image
	RgbImage image = cvCreateImage(cvSize(width, height), 8, 3);
	
	// foreground masks
	BwImage fgMask = cvCreateImage(cvSize(width, height), 8, 1);
	BwImage tempMask  = cvCreateImage(cvSize(width, height), 8, 1);
	cvZero(fgMask.Ptr());
	
	// create background model
	TextureArray* bgModel = new TextureArray[size];
	RgbImage texture = cvCreateImage(cvSize(width, height), 8, 3);
	unsigned char* modeArray = new unsigned char[size];
	TextureHistogram* curTextureHist = new TextureHistogram[size];
	
	// initialize background model
	unsigned int frameNum = 0;
	axisCam->GetImage(image.Ptr(), frameNum);
	LBP(image, texture);
	Histogram(texture, curTextureHist);
	for(int y = REGION_R+TEXTURE_R; y < height-REGION_R-TEXTURE_R; ++y)
	{
		for(int x = REGION_R+TEXTURE_R; x < width-REGION_R-TEXTURE_R; ++x)
		{
			int index = x+y*width;
			
			for(int m = 0; m < NUM_MODES; ++m)
			{
				for(int i = 0; i < NUM_BINS; ++i)
				{			
					bgModel[index].mode[m].r[i] = curTextureHist[index].r[i];
					bgModel[index].mode[m].g[i] = curTextureHist[index].g[i];
					bgModel[index].mode[m].b[i] = curTextureHist[index].b[i];
				}
			}
		}
	}

	// connected-components
	ConnectedComponents cc;
	
	// structuring element used for dilation and erosion
	IplConvKernel* dilateElement = cvCreateStructuringElementEx(7, 7, 3, 3,	CV_SHAPE_RECT);
	IplConvKernel* erodeElement = cvCreateStructuringElementEx(3, 3, 1, 1,	CV_SHAPE_RECT);
		
	cvNamedWindow("Before Post Processing",1);
	cvNamedWindow("Texture BGS",1);
	
	while(!gTerminate)
	{
		// get the new image
		axisCam->GetImage(image.Ptr(), frameNum);

		// preprocessing
		//cvSmooth(image.Ptr(), image.Ptr(), CV_GAUSSIAN, 3, 0, 0); 

		// perform background subtraction
		LBP(image, texture);
		Histogram(texture, curTextureHist);
		BgsCompare(bgModel, curTextureHist, modeArray, THRESHOLD, fgMask);
		
		cvShowImage("Before Post Processing", fgMask.Ptr());
		
		// size filtering
		CBlobResult largeBlobs;
		cc.SetImage(&fgMask);
		cc.Find(127);
		cc.FilterMinArea(size/30, largeBlobs);
		fgMask.Clear();
		CvScalar color = CV_RGB(255,255,255);
		cc.ColorBlobs(fgMask.Ptr(), largeBlobs, color);
		
		// morphological operators
		cvDilate(fgMask.Ptr(), fgMask.Ptr(), dilateElement, 1);
		cvErode(fgMask.Ptr(), fgMask.Ptr(), erodeElement, 1);
			
		// show results of background subtraction
		cvShowImage("Texture BGS", fgMask.Ptr());
		
		// update background subtraction		
		UpdateModel(fgMask, bgModel, curTextureHist, modeArray);
		
		// sleep for 10ms or until user presses a key
		int key = cvWaitKey(10);
		
		// check if user is finished (i.e., ESC is pressed)
		if((key&0xFF) == 27)	
		{
			gTerminate = true;
		}
	}
	
	cvReleaseStructuringElement(&dilateElement);
	cvReleaseStructuringElement(&erodeElement);
	
	cvDestroyWindow("Before Post Processing");
	cvDestroyWindow("Texture BGS");
	
	delete[] bgModel;
	delete[] modeArray;
	delete[] curTextureHist;
	
	return 0;
}

推荐答案

bgModel是一种结构(实际上是此类结构的数组,因此bgModel[index]选择在index偏移处的结构.在该结构内是由变量m索引的另一个结构数组(mode).在结构内是由(c5)索引的某种类型的数组(r).变量i.因此,该表达式的目标是mode数组的m结构的r数组的i项,在bgModelindex结构中同样,源项是curTextureHist结构数组的index项中r数组的i项,作为indexmi的值在for循环中增加,代码将选择数组中的不同项目.

如果不绘制图片,很难使它更清晰.
bgModel is a structure (actually an array of such structures, so bgModel[index] selects the structure at the offset of index. Within that structure is another array of structures (mode) which is indexed by the variable m. Within that structure is an array of some type (r) which is indexed by the variable i. So the target of this expression is the ith item of the r array in the mth structure of the mode array, in the indexth structure of the bgModel array. Similarly the source item is the ith item of the r array in the indexth item of the array of curTextureHist structures. As the values of index, m and i increase in the for loop, the code selects the different items in the arrays.

Without drawing a picture it is difficult to make it much clearer.


这篇关于C ++编程2中的问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆