error in program

Hey guys

I have been stuck on finding the error in my program, it's not a syntax error but its not performing the way i want it to.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
for(int l=0;l<int(lenx);l++)
	{
		for(int w=0;w<int(leny);w++)
		{
			for(int h=0;h<int(lenz);h++)
			{
				threedpoint.push_back(Point3f(l,w,h));		
				projectPoints(threedpoint,Rot,Tran,intrinsic,distCoeffs,projectedpoints);
				cout<<"X= "<<projectedpoints[0].x<<" Y= "<<projectedpoints[0].y<<endl;
				if((projectedpoints[0].x<480)&&(projectedpoints[0].x>0)&&(projectedpoints[0].y<640)&&(projectedpoints[0].y>0))
				{
				//access each element of threedimension.at<float>(x,y,z)
					check = threedimension.at<float>(l,w,h);
					if(check==1)   //-1 rows and -1 cols check into it, solved cannot check the matrix directly so assign it to a variable then check
					{
									vertexpoints.push_back(Point3f(l,w,h));
						if(float(mask.at<uchar>(projectedpoints[0]))==255)
						{
										threedimension.at<float>(l,w,h)=0;
						}
							
					}
				}
				projectedpoints.clear();
				threedpoint.clear();
			}
		}
	}


So the code calls projectpoints to convert the 3d coordinates to 2d, sometimes the function results with negative numbers which its not supposed to do but it does and secondly sometimes it produces a valid number e.g. 153, 533, but going through the next lines of code and at mask it causes exception error for no reason, the mask is 480 rows, 640 cols.

error:
X= 250.538 Y= 403.485
Opencv Error: Assertion failed (dims <= 2 && data && (unsigned)pt.y < )(unsigned)size.p[0] && (unsigned)(pt.x*DataType<_Tp>::channels) < (unsigned)(size.p[1]*channels()) & ((((sizeof(size_t)<<28)|0x8442211) >> ((DataType<_Tp>::depth) & ((1 << 3) - 1)*4) & 15) == elemSize1()) in unknown function, file .....mat.hpp line 553

any help?
thanks
Last edited on
asda333 wrote:
I have been stuck on finding the error in my program, it's not a syntax error but its not performing the way i want it to.


Have you considered using a debugger? Will save you DAYS of staring at code. IF you are using an IDE it should be easy - there should be a debug menu. You can step through the code 1 line at a time, keep an eye on the value of the variables, and deduce where it all goes wrong.

Aside from that, I have these comments:

Your condition on line 10 could be a function of it's own: bool PtInRect(int x, int y){} . It just makes it much easier to understand at a glance.

What does line 13 do - the at function I mean?

Line 17 looks like a C cast to float, but without the parentheses - but that doesn't make sense, it should be an integral type to make a comparison.

Don't use magic numbers like 640, 480 in your code, use const variables instead.

Hope all goes well.

EDIT: I just realised that one can have functional type casting, but line 17 still doesn't make sense to me.
Last edited on
Yes, I always use a debugger it just crashes at mask.at.

lol, i never stare at codes, i always step through it.
i print out the variables and see it going negative than normal and then using that normal variable it crashes.

i still don't know why it says mask is not big enough for the 2d points.

i can change it to function, thanks for that advice.

what line 13 does it checks the element of the 3d array threedimension and stores the value in that position in the array and then use if function to check if it is a zero or a one.

check = threedimension.at<float>(l,w,h);

as it won't let me do if(threedimensiona.at<float>(l,w,h)==1){...}

so instead of float(mask.at<uchar...) it should be int(mask.at) ok i will give that a try.

so use const variables to store it, makes sense.

i don't understand what you mean by functional type casting, but line 17 compares the value of the mask at the 2d coordinate point to see if it is foreground i.e. 0 value black or 255 white background or foreground as the mask is a binary image and want to see if certain coordinates from projectpoints function in the mask is black or white.

thanks

EDIT:
this is what it looks like now

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
for(int l=0;l<int(lenx);l++)
{
	for(int w=0;w<int(leny);w++)
	{
		for(int h=0;h<int(lenz);h++)
		{
			threedpoint.push_back(Point3f(l,w,h));		
			projectPoints(threedpoint,Rot,Tran,intrinsic,distCoeffs,projectedpoints);
			cout<<"X= "<<projectedpoints[0].x<<" Y= "<<projectedpoints[0].y<<endl;
			if(PtInRect(projectedpoints[0].x,projectedpoints[0].y)==1)
			{
				//access each element of threedimension.at<float>(x,y,z)
				check = threedimension.at<float>(l,w,h);
				if(check==1)   //-1 rows and -1 cols check into it, solved cannot check the matrix directly so assign it to a variable then check
				{
					vertexpoints.push_back(Point3f(l,w,h));
					if(int(mask.at<uchar>(projectedpoints[0]))==255)
					{
						threedimension.at<float>(l,w,h)=0;
					}
			
				}
			}
			projectedpoints.clear();
			threedpoint.clear();
		}
	}
}


is this how you wanted it. i have also added global const variables for length and width 480 and 640.

will step through it to see if it works.
Last edited on
Functional style casting looks like this :

MyFloat = float(Variable); because it looks like a function call - which is what you are doing. But you seem to convert things to float that look like they should be integers or unsigned.

as opposed to C style casting :

MyFloat = (float)Variable;

Then there is C++ casting :

MyFloat = static_cast<float>(Variable);

With this :

check = threedimension.at<float>(l,w,h);

It looks like the float type refers to type of the value in the 3d array, so the return value will be this type also? If it is a return type, then check is a float, so if(check==1) probably wont work very well.

Any way I hope this has been some help - I am going to bed now it's 01:30AM at this end. Cheers

thanks

the problem still seems to persist.
so it should be int

like
check = threedimension.at<int>(l,w,h);

i tried debugging it through and it crashed at 1,0,2
with length of each is 17,17,10

and same error, i don't understand, will change it to int instead of float.

in case i set up the threedimension matrix like this

int sz[] = {lenx,leny,lenz};
Mat threedimension(3,sz,CV_32F,Scalar::all(1));

and mask like this

Mat mask = Mat::zeros(camlen, camwidth, CV_8UC1); //create matrix same size as image which is 480 by 640 based on the webcam capture
camlen and camwidth are const doubles

because i wanted to create a 3d array and opencvdocs recommended it this way.

filled with 1s its a 32bit floating point array so thats why i did
check=threedimension.at<float>(l,w,h)

so maybe i should change if check==1 to check==1.0;

thanks for helping in such an inconvenient time and it has been helpful, when you get time tomorrow would appreciate some help on other things i can do.

that error is just crazy confusing.
thanks
Last edited on
I just decided to step through around 50+ times until i reach 1,1,0 and when i was on check=threedimension.at<int>(l,w,h);
check =1065353216

whaat! how did it get that number, all points in the threedimension are 1s and are turned to zeros if they are ones and the corresponding 2d point in the mask corresponds to the white area.

how did that happen.

maybe i should place that inside the ptInRect function.
i don't know.

but one why is projectpoints giving me negative numbers.
Hi,

I don't know a lot about what you are doing here (am flying by the seat of my pants), I had a quick read of the opencv documentation, but I am confused.

One small thing first If PtInRect returns a bool, there is no need to compare to 1, just do this:

if( PtInRect(projectedpoints[0].x,projectedpoints[0].y) )

I am confused by Lines 1 to 7 in your code: There is more than 1 z value for each x,y value. If lenz is 10 say, there will be 10 z values for each x,y point - how does that work with the transformation on line 8? I would have expected 1 z value for each x,y point

Once you do the transformation, you have a 2D array of floats - how were you expecting those to be 0 or 255 unsigned values? Something to do with the camera matrix, I am guessing, but none the less projectedpoints is a 2D array of floats according to my reading of the documentation. So there will be problems with PtInRect as well - when I suggested that, I thought the points would be unsigned.

Also, you are only sending 1 point to the projectPoints function (because you clear them both on lines 24 & 25), shouldn't you be sending all of them at once? So create your 3d points first, then send the whole thing to the projectPoints function.

Is this code for testing? Because you only test the very first value in projectedpoints. So the nested for loops are a bit pointless. In my mind, the call to projectPoints and the testing of its result should be outside the loops.

Line 13 still returns a float, so the comparison between it and an int won't work on line 14. Comparison with a float and 0.0 never works either because floats are stored as binary fractions.

So, a summary of what your code does:

- A threedpoint is created, presumably converting the 3 ints into floats. But no data value is assigned to the 3d coordinate.
- The projectPoints function is called, the result is in projectedpoints (a 2d array of floats) presumably this is supposed in the range (0.0,0.0) to (640.0,480.0)
- A check is made to see whether the projected point is in (0.0,0.0) to (640.0,480.0). There seems to be no copying of the data into a 640 by 480 array.
- You then check a value in threedimension which looks like it has been initialised to 1.0's (floats), to see if it is 1 (int) - that comparison will always fail
- The original l, w, h float values are pushed into a new container vertexpoints.
- The value in the mask container is checked to see if it is 255 (int), but this was initialised with 0's (unsigned 8 bit) and it hasn't changed since then.
- If that was true then the threedimension value is set to 0 (int), but threedimension is floats, but this seems to strangely have nothing to do with the projectedpoints container.
- The clear method is called for projectedpoints & threedpoint.

So, some really confused ideas happening here. In my mind perhaps it should go like this:

> Create an array of data with a 3D point (1 z value for each x,y point) and a colour value. What is the value and type of the data at that 3d point? Is it an unsigned value representing a colour? Don't confuse it with the dimensions of the array.

> Transform the whole thing in one call to projectPoints. Make sure the transformation parameters are set up so that resulting projectedpoints produces 2d points in the range (0.0,0.0) to (640.0 480.0). Can use the PtInReact function here to check that it worked. Make sure that function works with floats - can't use the == operator. We needed float values for the coords in order to do the transformation, but the data itself (the colour) is still unsigned.

> Copy the value of the colour into the 640 by 480 image array - need to cast the 2d float coords in projectedpoints to unsigned 16 bit, to come up with the subscripts in the image array.

> Must have some way of deciding whether a value is 0 or 255, not sure whether this happens in the projectPoints call, or whether the colour value doesn't change. If not you should write your own function to do that.

As I said at the start, I don't have any experience with what you are doing - I don't know the details of the library, but I do know about co-ord transformation, and I think I have managed to figure out what you are wanting to do. But if I have any of it backwards or inside out - let me know :+)



Noo! i wrote soo much and when i clicked reply it said too long and then i didn't get to copy it i have to write it again.

here we go again.


Hi,

I don't know a lot about what you are doing here (am flying by the seat of my pants), I had a quick read of the opencv documentation, but I am confused.

One small thing first If PtInRect returns a bool, there is no need to compare to 1, just do this:

if( PtInRect(projectedpoints[0].x,projectedpoints[0].y) )


fine, will do.


I am confused by Lines 1 to 7 in your code: There is more than 1 z value for each x,y value. If lenz is 10 say, there will be 10 z values for each x,y point - how does that work with the transformation on line 8? I would have expected 1 z value for each x,y point


the loop is actually just generating the 3D points to use for the projectpoints function, so if i have a dimension of x=10, y=10, z=10
i want to generate the 3d points 0,0,0 0,0,1 all the way upto 9,9,9

should i do it reverse with x in the centre of the nested loops and z on the outside of the nested loops.

Once you do the transformation, you have a 2D array of floats - how were you expecting those to be 0 or 255 unsigned values? Something to do with the camera matrix,
[/quote
they are 0 or 255 from the image segmentation process, which generated a mask made up of black and white elements, i didn't mention my mistake.
the camera parameters are the intrinsic, rot, tran in the projectpoints function.

[quote]I am guessing, but none the less projectedpoints is a 2D array of floats according to my reading of the documentation. So there will be problems with PtInRect as well - when I suggested that, I thought the points would be unsigned.


i changed it to float x and float y in the function declaration.


Also, you are only sending 1 point to the projectPoints function (because you clear them both on lines 24 & 25), shouldn't you be sending all of them at once? So create your 3d points first, then send the whole thing to the projectPoints function.
Is this code for testing? Because you only test the very first value in projectedpoints. So the nested for loops are a bit pointless. In my mind, the call to projectPoints and the testing of its result should be outside the loops.



i was sending only one so i can generate only one and then i can process each one individually. i can try converting all the points and then process each one. will try

Line 13 still returns a float, so the comparison between it and an int won't work on line 14. Comparison with a float and 0.0 never works either because floats are stored as binary fractions.


so should i change it to

float check=0.0;
check = threedimension.at<float>(l,w,h);

if i can't use == operator for if(check==1) what else should i use.


So, a summary of what your code does:

- A threedpoint is created, presumably converting the 3 ints into floats. But no data value is assigned to the 3d coordinate.

exactly, no data is stored at the 3d points, the only interest is the actual 3d coordinates.

- The projectPoints function is called, the result is in projectedpoints (a 2d array of floats) presumably this is supposed in the range (0.0,0.0) to (640.0,480.0)
- A check is made to see whether the projected point is in (0.0,0.0) to (640.0,480.0). There seems to be no copying of the data into a 640 by 480 array.

that is true, no change is made to the mask, only value of the pixel at the 2d coordinate is checked on the mask only.

- You then check a value in threedimension which looks like it has been initialised to 1.0's (floats), to see if it is 1 (int) - that comparison will always fail

correct, i check if it is 1, so i make check a float but how would i check if it is 1 or not.

- The original l, w, h float values are pushed into a new container vertexpoints.
- The value in the mask container is checked to see if it is 255 (int), but this was initialised with 0's (unsigned 8 bit) and it hasn't changed since then.

this mask was changed during the image segmentation process, which fills it with 255s or 0s.

- If that was true then the threedimension value is set to 0 (int), but threedimension is floats, but this seems to strangely have nothing to do with the projectedpoints container.
- The clear method is called for projectedpoints & threedpoint.

yup, it is set to zero if the value of the mask at the 2d coordinate is black. 0

So, some really confused ideas happening here. In my mind perhaps it should go like this:

> Create an array of data with a 3D point (1 z value for each x,y point) and a colour value. What is the value and type of the data at that 3d point? Is it an unsigned value representing a colour? Don't confuse it with the dimensions of the array.


3d points contain no data, only the 3d coordinates themselves are important.

> Transform the whole thing in one call to projectPoints. Make sure the transformation parameters are set up so that resulting projectedpoints produces 2d points in the range (0.0,0.0) to (640.0 480.0). Can use the PtInReact function here to check that it worked. Make sure that function works with floats - can't use the == operator. We needed float values for the coords in order to do the transformation, but the data itself (the colour) is still unsigned.

sure i can do that, but since i can't use the == operator to check for floats what can i use.
there is no colour value.

> Copy the value of the colour into the 640 by 480 image array - need to cast the 2d float coords in projectedpoints to unsigned 16 bit, to come up with the subscripts in the image array.
no change is necessary to be performed on the 640 by 480 image array as it is only for referencing.

> Must have some way of deciding whether a value is 0 or 255, not sure whether this happens in the projectPoints call, or whether the colour value doesn't change. If not you should write your own function to do that.


this happens in this code

if(int(mask.at<uchar>(projectedpoints[0]))==255)

As I said at the start, I don't have any experience with what you are doing - I don't know the details of the library, but I do know about co-ord transformation, and I think I have managed to figure out what you are wanting to do. But if I have any of it backwards or inside out - let me know :+)


You got a good guess i just didn't explain myself, so i have included more info so hopefully it should help you and give tip based on those info.

so what my code does

mask is generated previously from image segmentation function and a binary image made up of 255s and 0s is generated this is before the for loop i have added.

then x,y,z corners are generated and is fed into the project points function, the 2d point is used as a coordinate to be used on the mask to see if it is a black or white element.

also 3d array element checked if it is a one or a zero, if one and the mask is a black element the 3d array is assigned zero and this is repeated for all the 3d coordinates.

thanks
;)
Thanks for your detailed reply.

Now that you have your other topic with all the code in, how about you discontinue this one? Have all the discussion in one place.
one more thing

cout<<threedimension.at<int>(1,1,2);

prints

1065353216

i don't know why, its supposed to be 1.

projectpoints function is still giving values bigger than 480 and 640
upto 1000 which is crazy, i don't know why.

EDIT:
changed it to threedimension.at<float>(l,w,h) equals one
no high numbers

i think the image is 480 rows 640 cols
same with mask
Last edited on
Topic archived. No new replies allowed.