C ++编程2中的问题 [英] problem in c++ programing 2
本文介绍了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
项,在bgModel
的index
结构中同样,源项是curTextureHist
结构数组的index
项中r
数组的i
项,作为index
,m
和i
的值在for
循环中增加,代码将选择数组中的不同项目.
如果不绘制图片,很难使它更清晰.
bgModel
is a structure (actually an array of such structures, sobgModel[index]
selects the structure at the offset ofindex
. Within that structure is another array of structures (mode
) which is indexed by the variablem
. Within that structure is an array of some type (r
) which is indexed by the variablei
. So the target of this expression is thei
th item of ther
array in them
th structure of themode
array, in theindex
th structure of thebgModel
array. Similarly the source item is thei
th item of ther
array in theindex
th item of the array ofcurTextureHist
structures. As the values ofindex
,m
andi
increase in thefor
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屋!
查看全文