C++ code for Microsoft Kinect - trying to dynamically allocate array of target positions - c++

So I'm trying to modify the Kinect BodyBasicsD2D code so that a fixed number of "target positions" appear on the screen (as ellipses) for the user to move his hand toward. I'm having trouble creating the initial target positions.
This is my code in the header file for the allocation of the array of target positions (these are a public field of the CBodyBasics class, already built into the original BodyToBasics program):
D2D1_POINT_2F* targetPositions = NULL;
int numTargets = 3;
Then I have a function "GenerateTargetPositions" which is supposed to generate 3, in this case, target positions to be passed into the "DrawTargetPositions" function.
void CBodyBasics::GenerateTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
targetPositions = new D2D1_POINT_2F[numTargets];
RECT rct;
GetClientRect(GetDlgItem(m_hWnd, IDC_VIDEOVIEW), &rct);
int width = rct.right;
int height = rct.bottom;
FLOAT x;
FLOAT y;
D2D1_POINT_2F tempPoint;
for (int i = 0; i < numTargets; i++) {
x = 1.0f*i*width / numTargets;
y = 1.0f*i*height / numTargets;
tempPoint = D2D1::Point2F(x, y);
targetPositions[i] = tempPoint;
}
}
My DrawTargetPositions function is:
void CBodyBasics::DrawTargetPositions(D2D1_POINT_2F * targetPositions, int numTargets)
{
D2D1_ELLIPSE ellipse;
for (int i = 0; i < numTargets; i++)
{
ellipse = D2D1::Ellipse(targetPositions[i], 50.f, 50.f);
m_pRenderTarget->FillEllipse(ellipse, m_pSilverBrush);
}
}
When I try to run my code, I get the error that both "targetPositions" and "targetPositions[i]" is NULL (and thus my GenerateTargetPositions function must not be working properly). I believe that targetPositions[i] is a struct (a point with x and y values) so I am wondering if this may be the reason for my errors.
I call GenerateTargetPositions and DrawTargetPositions before the main "while" loop in my code so that each function is not being called on each iteration (there are many iterations of through the while loop because this is an interactive Microsoft Kinect, recording one's movements).
Any suggestions and advice would be greatly appreciated. Thanks so much!

Related

Why are the contents of these pointers changing inside this Vector and throwing a read access violation exception?

Basically, I am finishing a game engine, and one of the processes is to evaluate collision detection between colliders.
The problem is, is that the gameObjects/colliders I collect from the game map seems to completely change after several iterations of searching for collision detections.
Below shows how I obtained these colliders, I give the game map an empty vector called mapObjects so that it fills the vector with game objects
Game.cpp
vector<SimObject*> mapObjects;
currentMap = new GameMap("GameMap.txt", mapObjects, *texManager);
renderer->SetScreenProperties(16, currentMap->GetMapWidth(), currentMap->GetMapHeight());
for (int i = 0; i < mapObjects.size(); i++) {
AddNewObject(mapObjects[i]);
}
Then the map objects get processed through a function, which is put onto another vector and also dissected to place the collider and the rigid body into two other different vectors, allColliders and allBodies:
Game.cpp
void Game::AddNewObject(SimObject* object) {
newObjects.emplace_back(object);
physics->AddRigidBody(object);
if (object->GetCollider()) {
physics->AddCollider(object->GetCollider());
}
}
The way the game map obtains these objects is by evaluating the game map data, transforms these into Vector4 instances containing x, y, width and height, then is iterated and transformed into game objects for e.g. finding the walls:
GameMap.cpp
for (int i = 0; i < walls.size(); i++) {
Wall* wall = new Wall(walls[i]);
objects.emplace_back(wall);
}
Inside the wall constructor, this happens:
Wall::Wall(Vector4 vec) : StaticObject(vec)
which the following involves this basically:
StaticObject::StaticObject(Vector4 vec)
{
float midX = vec.x + ((vec.z - vec.x) / 2.0f);
float midY = vec.y + ((vec.w - vec.y) / 2.0f);
SetPosition(Vector2(midX, midY));
float halfW = midX - vec.x;
float halfH = midY - vec.y;
SetCollider(new CollisionVolume(this, Vector2(halfW, halfH)));
fixed = true;
}
Everything works fine at first, but after several iterations of this:
Game.cpp
void GameSimsPhysics::CollisionDetection(float dt) {
for (int i = 0; i < allColliders.size(); ++i) {
for (int j = i + 1; j < allColliders.size(); ++j) {
allColliders[i]->DetectCollision(*allColliders[j]);
}
}
}
A read access violation is thrown:
Unhandled exception thrown: read access violation.
this was 0xFFFFFFFFFFFFFFFF.
I had an investigate through the debugger, and it says that it is unable to read memory of the contents. However, if game objects were added within Game.cpp just after finding the map objects, their contents seem to be still in tact and unchanged:
player = new PlayerCharacter();
player->SetPosition(Vector2(100, 32));
player->SetCollider(new CollisionVolume(player, 10.0f));
AddNewObject(player);
I am really unsure and stuck at the moment, so I will appreciate any help! I have tried to keep it as simple as possible, but let me know if more information is needed.

Why am I getting Undefined Behavior (EXC_BAD_ACCESS (code=1, address=0x1177c1530)) when I access a position of a matrix (opencv mat) on Xcode

I am trying to develop a c++ program with opencv library on Xcode 9.3, macOS 10.14, using clang. During weeks I've been trying to solve or understand why I am getting an undefined behavior error that sometimes makes my program crash and sometimes not.
I am reading a set of images from different cameras and storing them in a multidimensional array: silC[camera][image]. (images are well stored)
I get this error THREAD 1: EXC_BAD_ACCESS (code=1, address=0x1177c1530) when I do this: currentImage.at(x,y) even the values of currentImage are not the problem nor the image.
I post the code below if there's any chance someone could help me..
vector< vector<Mat> > silC(8,vector<Mat>()); // Store the pbm images separating from different cameras
* I read the images and store them in silC. *
for (int z=0; z < nz; z++) {
for (int y=0; y < ny; y++) {
for (int x=0; x < nx; x++) {
// Current voxel coordinates in the 3D space
float xcoord = x*voxelsize + Ox + voxelsize/2;
float ycoord = y*voxelsize + Oy + voxelsize/2;
float zcoord = z*voxelsize + Oz + voxelsize/2;
for (int camId=0; camId < matricesP.size(); camId++) {
imgId = 0;
currentImage = silC[camId][imgId];
int w = silC[camId][imgId].cols;
int h = silC[camId][imgId].rows;
// Project the voxel from the 3D space to the images
Mat P = matricesP[camId];
Mat projection = P*(Mat_<float>(4,1) << xcoord,ycoord,zcoord,1.0);
//We get the point in homog coord.
float xp = projection.at<float>(0);
float yp = projection.at<float>(1);
float zp = projection.at<float>(2);
// Get the cartesian coord
int xp2d = cvRound(xp/zp);
int yp2d = cvRound(yp/zp);
if(xp2d >= 0 && xp2d < w && yp2d >= 0 && yp2d < h){
// all values are correct! :/
// int value = silC[camId][imgId].at<float>(xp2d, yp2d); // undefined behaviour: crashes sometimes..
int value = currentImage.at<float>(xp2d, yp2d); // undefined behaviour also crashes sometimes..
if(value == 255){
cout << "Voxel okey \n";
}
}
}
}
}
}
EDIT:
The solution posted on comments below is that instead of currentImage.at(xp2d,yp2d) --> currentImage.at(yp2d,xp2d), as cv::Mat access requieres.
BUT, I tried to parallelize the for several times with openMP (#pragma omp parallel for) but it kept crashing. If someone is familiar with parallelize I'll appreciate any help.
the solution is what #rafix07 posted. Thank you very much guys, next time I'll try to focus more.

Tile mapping error

I am still learning SFML and C++ so please understand that I'm still at the basic level.
This is my first time using this site so IDK if I'm doing this right.
I want to make a function, set, that will allow me to pass a 2d array as an argument and place a tile down whenever there is a 1 in the array. So I can draw maps and things using a matrix. ww is the window width and wh is the window height. In main I made a for loop that would go through tiles and draw them to the window. But when I run this it gives me the error: Segmentation Fault (core dumped) "Error: 139". Is there a better way of doing this and what am I doing wrong?
Thank you.
struct field
{
int rectsizex;
int rectsizey;
RectangleShape * tiles;
field (int s)
{
rectsizex = ww / s;
rectsizey = wh / s;
tiles = new RectangleShape[rectsizex * rectsizey];
}
~field()
{
delete tiles;
}
RectangleShape * set(int ** matr)
{
Vector2f size((ww / rectsizex), (wh / rectsizey));
int posx = ww / rectsizex;
int posy = wh / rectsizey;
for(int x = 0; x<rectsizex; x++)
{
for(int y = 0; y<rectsizey; y++)
{
int i = ((x*rectsizey)+1)+y;
tiles[i].setSize(size);
if(matr[x][y] == 1)
{
tiles[i].setFillColor(Color::Black);
}
else
{
tiles[i].setFillColor(Color::White);
}
tiles[i].setPosition(x * posx, y * posy);
}
}
return tiles;
}
};
Find out what values you are getting for i:
int i = ((x*rectsizey)+1)+y;
This value is definitely outside of your array bounds, hence the error. Use a debugger, or put some print statements after you get the i value.

Finding Local Maxima Grayscale Image opencv

I am trying to create my personal Blob Detection algorithm
As far as I know I first must create different Gaussian Kernels with different sigmas (which I am doing using Mat kernel= getGaussianKernel(x,y);) Then get the Laplacian of that kernel and then filter the Image with that so I create my scalespace. Now I need to find the Local Maximas in each result Image of the scalespace. But I cannot seem to find a proper way to do so.... my Code so far is
vector <Point> GetLocalMaxima(const cv::Mat Src,int MatchingSize, int Threshold)
{
vector <Point> vMaxLoc(0);
if ((MatchingSize % 2 == 0) ) // MatchingSize has to be "odd" and > 0
{
return vMaxLoc;
}
vMaxLoc.reserve(100); // Reserve place for fast access
Mat ProcessImg = Src.clone();
int W = Src.cols;
int H = Src.rows;
int SearchWidth = W - MatchingSize;
int SearchHeight = H - MatchingSize;
int MatchingSquareCenter = MatchingSize/2;
uchar* pProcess = (uchar *) ProcessImg.data; // The pointer to image Data
int Shift = MatchingSquareCenter * ( W + 1);
int k = 0;
for(int y=0; y < SearchHeight; ++y)
{
int m = k + Shift;
for(int x=0;x < SearchWidth ; ++x)
{
if (pProcess[m++] >= Threshold)
{
Point LocMax;
Mat mROI(ProcessImg, Rect(x,y,MatchingSize,MatchingSize));
minMaxLoc(mROI,NULL,NULL,NULL,&LocMax);
if (LocMax.x == MatchingSquareCenter && LocMax.y == MatchingSquareCenter)
{
vMaxLoc.push_back(Point( x+LocMax.x,y + LocMax.y ));
// imshow("W1",mROI);cvWaitKey(0); //For gebug
}
}
}
k += W;
}
return vMaxLoc;
}
which I found in this thread here, which it supposedly returns a vector of points where the maximas are. it does return a vector of points but all the x and y coordinates of each point are always -17891602... What to do???
Please if you are to lead me in something else other than correcting my code be informative because I know nothing about opencv. I am just learning
The problem here is that your LocMax point is declared inside the inner loop and never initialized, so it's returning garbage data every time. If you look back at the StackOverflow question you linked, you'll see that their similar variable Point maxLoc(0,0) is declared at the top and constructed to point at the middle of the search window. It only needs to be initialized once. Subsequent loop iterations will replace the value with the minMaxLoc function result.
In summary, remove this line in your inner loop:
Point LocMax; // delete this
And add a slightly altered version near the top:
vector <Point> vMaxLoc(0); // This was your original first line
Point LocMax(0,0); // your new second line
That should get you started anyway.
I found it guys. The problem was my threshold was too high. I do not understand why it gave me negative points instead of zero points but lowering the threshold worked

C++ vector element is different when accessed at different times

I'm developing a 3D game using SDL and OpenGL on Ubuntu 9.04 using Eclipse CDT. I've got a class to hold the mesh data in vectors for each type. Such as Vertex, Normal, UVcoord (texture coordinates), as well as a vector of faces. Each face has 3 int vectors which hold indexes to the other data. So far my game has been working quite well at rendering at nice rates. But then again I only had less then one hundred vertexes among two objects for testing purposes.
The loop accessing this data looks like this:
void RenderFace(oFace face)
{
/*
* More Stuff
*/
oVertice gvert;
oUVcoord tvert;
oNormal nvert;
for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++)
{
gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1);
tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1);
nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1);
glNormal3f(nvert.X, nvert.Y, nvert.Z);
glTexCoord2f(tvert.U, tvert.V);
glVertex3f(scale * gvert.X, scale * gvert.Y, scale * gvert.Z);
}
/*
* More Stuff
*/
}
There is a loop that calls the renderFace() function which includes the above for loop. The minus one is because Wavefront .obj files are 1 indexed (instead of c++ 0 index). Anyway, I discovered that once you have about 30 thousand or so faces, all those calls to glVertex3f() and the like slow the game down to about 10 FPS. That I can't allow. So I learned about vertex arrays, which require pointers to arrays. Following the example of a NeHe tutorial I continued to use my oVertice class and the others. Which just have floats x, y, z, or u, v. So I added the same function above to my OnLoad() function to build the arrays which are just "oVertice*" and similar.
Here is the code:
bool oEntity::OnLoad(std::string FileName)
{
if (!obj.OnLoad(FileName))
{
return false;
}
unsigned int flsize = obj.TheMesh.GetFaceListSize();
obj.TheMesh.VertListPointer = new oVertice[flsize];
obj.TheMesh.UVlistPointer = new oUVcoord[flsize];
obj.TheMesh.NormListPointer = new oNormal[flsize];
oFace face = obj.TheMesh.GetFace(0);
oVertice gvert;
oUVcoord tvert;
oNormal nvert;
unsigned int counter = 0;
unsigned int temp = 0;
for (unsigned int flIndex = 0; flIndex < obj.TheMesh.GetFaceListSize(); flIndex++)
{
face = obj.TheMesh.GetFace(flIndex);
for (unsigned int fvIndex = 0; fvIndex < face.GeoVerts.size(); fvIndex++)
{
temp = face.GeoVerts[fvIndex];
gvert = obj.TheMesh.GetVertice(face.GeoVerts[fvIndex] - 1);
temp = face.UV_Verts[fvIndex];
tvert = obj.TheMesh.GetUVcoord(face.UV_Verts[fvIndex] - 1);
temp = face.NrmVerts[fvIndex];
nvert = obj.TheMesh.GetNormal(face.NrmVerts[fvIndex] - 1);
obj.TheMesh.VertListPointer[counter].X = gvert.X;
obj.TheMesh.VertListPointer[counter].Y = gvert.Y;
obj.TheMesh.VertListPointer[counter].Z = gvert.Z;
obj.TheMesh.UVlistPointer[counter].U = tvert.U;
obj.TheMesh.UVlistPointer[counter].V = tvert.V;
obj.TheMesh.NormListPointer[counter].X = nvert.X;
obj.TheMesh.NormListPointer[counter].Y = nvert.Y;
obj.TheMesh.NormListPointer[counter].Z = nvert.Z;
counter++;
}
}
return true;
}
The unsigned int temp variable is for debugging purposes. Apparently I don't have a default constructor for oFace that doesn't have something to initialize with. Anyway, as you can see it's pretty much that same exact routine. Only instead of calling a gl function I add the data to three arrays.
Here's the kicker:
I'm loading a typical cube made of triangles.
When I access element 16 (0 indexed) of the UV_Verts vector from the RenderFace() function I get 12.
But when I access element 16 (0 indexed) of the same UV_Verts vector from the OnLoad() function I get something like 3045472189
I am so confused.
Does anyone know what's causing this? And if so how to resolve it?
One possible reason could be that you're creating arrays with size flsize:
obj.TheMesh.VertListPointer = new oVertice[flsize];
obj.TheMesh.UVlistPointer = new oUVcoord[flsize];
obj.TheMesh.NormListPointer = new oNormal[flsize];
but use the arrays with indices up to flsize * face.GeoVerts.size
for (...; flIndex < obj.TheMesh.GetFaceListSize(); ...) { // flsize = GetFaceListSize
for (...; fvIndex < face.GeoVerts.size(); ...) {
...
obj.TheMesh.UVlistPointer[counter].U = ...;
...
counter++;
}
}
so your array creation code should actually be more like
obj.TheMesh.VertListPointer = new oVertice[flsize * face.GeoVerts.size()];
obj.TheMesh.UVlistPointer = new oUVcoord[flsize * face.GeoVerts.size()];
obj.TheMesh.NormListPointer = new oNormal[flsize * face.GeoVerts.size()];