Finding a rectangle area

Hello,
I am writing a function for a project I am working with. What I want it to do is find a rectangle area that is in the range given. Here is what I have so far. I am open to ideas, but I don't want to include any other libraries if at all possible.
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
29
30
31
32
33
34
35
36
37
38
39
40
	RECT FindDepth(unsigned short SearchDepth, int Variation)
	{
		bool found = false;
		int maxW = 0, rowW = 0, rowStart = 0, endY = 0;
		int startX = 640, startY = -1;
		//unsigned int TotalDepth = 0;
		unsigned short Depth;

		for (int y = 0, i=0; y < 480; y++)
		{
			rowW = 0;
			for (int x = 0; x < 640; x++, i++)
			{
				Depth = mKinect->mDepthBuffer[i];
				if (Depth < SearchDepth + Variation && Depth > SearchDepth - Variation)
				{
					rowW++;
					if (rowW == 1) // Save the start of the row's x pos
						rowStart = x;
					//TotalDepth += Depth;

				}
				else if (rowW > 0) // If the depth doesn't match but its not the first match in the row
				{
					break;
				}
			}

			if (rowW > maxW) // Update the max width only if it is the largest yet
				maxW = rowW;
			if (rowW && startY == -1) // Find the first y to have a match
				startY = y;
			if (rowStart < startX) // Find the first horozontal match
				startX = rowStart;
			if (maxW && rowW == 0) // This makes sure that we match only one solid object
				break;
		}
		RECT rect = {startX, endY, maxW, startY};
		return (rect);
	}

If you look at the first line of the inner loop it sets Depth. This will be a value between 0 and 2024 (about). An example call to the function would be:
RECT found = FindDepth(850, 100);
The reason it is (over) complicated is I want it to match only solid objects. It shouldn't match two separate things in the image.

If you need more info just ask!


Another thing to note is it matches the upper left corner of the image when there is no object it should match, but when there is an object in the image it shrinks (or maybe grows) so much that I can't see it (by "can't see it" I mean that I draw the rectangle onto the image).
Last edited on
Anyone have an idea?
I now realize that my code above is not testable. Here is a stub that you can test:
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
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
#include <iostream>

using namespace std;

unsigned short mDepthBuffer[480*640];

	void FindDepth(unsigned short SearchDepth, int Variation, int& top, int& left, int& bottom, int& right)
	{
		bool found = false;
		int rowW = 0, rowStart = 640;
		right = 0;
		left = 640;
		bottom = 0;
	    top = -1;
		//unsigned int TotalDepth = 0;
		unsigned short Depth;

		for (int y = 0, i=0; y < 480; y++)
		{
			rowW = 0;
			for (int x = 0; x < 640; x++, i++)
			{
				Depth = mDepthBuffer[i];
				if (Depth < SearchDepth + Variation && Depth > SearchDepth - Variation)
				{
					rowW++;
					if (rowW == 1) // Save the start of the row's x pos
						rowStart = x;
					//TotalDepth += Depth;

				}
				else if (rowW > 0) // If the depth doesn't match but its not the first match in the row
				{
					break;
				}
			}

			if (rowW > right) // Update the max width only if it is the largest yet
				right = rowW;
			if (rowW && top == -1) // Find the first y to have a match
				top = y;
			if (rowStart < left) // Find the first horozontal match
				left = rowStart;
			if (right && rowW == 0) // This makes sure that we match only one solid object
				bottom = y - 1; break;
		}
		right += left;  // Make them coords
		bottom += top;
		return;
	}
	
	void MakeDepth()
	{
         for (int y = 0, i = 0; y < 480; y++)
         {
             for(int x = 0; x < 640; x++, i++)
             {
                     if (x > 100 && x < 300 && y > 50 && y < 250)
                        mDepthBuffer[i] = 901;
                     else 
                          mDepthBuffer[i] = 1500;
             }
         }
         return;
}
	
	int main()
	{
        int top, left, bottom, right;
        cout << "Creating...";
        MakeDepth();
        cout << "Finding...";
        FindDepth(900, 50, top, left, bottom, right);
        cout << "(" << left << ", " << top << ")\t"
             << "(" << right << ", " << bottom << ")\n";
        cin.ignore();
 }

Desired result from this code would be:
Creating...Finding...
(100, 50)
(300, 250)


Thanks,
Frankie
Have you tried using a 2 dimensional array for mDepthBuffer? It will make the problem much easier to visualize.
I could replace the Depth line:
1
2
3
4
//From
Depth = mDepthBuffer[i];
//To
Depth = mDepthBuffer[x + (y*640)];

But that doesn't really solve my problem.

Thanks for the idea.
I don't think you understand the syntax for a 2-d array. Your declaration of mDepthBuffer should look like this:
mDepthBuffer[x][y]
You'll also have to change your code slightly. Change all mDepthBuffer[i] to mDepthBuffer[x][y]. You can even get rid of the i variable. However, I did this on my computer and got a run time error. Probably from trying to allocate memory for the array.
mDepthBuffer is set outside the function. I could change the function that declares mDepthBuffer, but I didn't write it and I would like not to mess with it. It is used in various places throughout the code.
Do you have any ideas as to what might cause me to get incorrect output from the above function and maybe a possible fix?

Thanks,
Frankie
After Looking at this thing for at least an hour I finally found something! Delete the break; on line 45. It is causing the loop to end early. Do this and you're output will be

Creating...Finding...(101, 51)   (300, 529)
Thank you! That is part of the problem. A big part for sure.
The other part is that there will be multiple matches in the real world application of this function. If you change the code for MakeDepth (it creates the test data) it now has two rectangles and the function doesn't work anymore.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
	void MakeDepth()
	{
         for (int y = 0, i = 0; y < 480; y++)
         {
             for(int x = 0; x < 640; x++, i++)
             {
                     if (x >= 50 && x < 100 && y >= 50 && y < 110)
                        mDepthBuffer[i] = 900;
                     else if (x >= 200 && x < 250 && y >= 60 && y < 200) // Add another object to the test
                          mDepthBuffer[i] = 900;
                     else 
                          mDepthBuffer[i] = 1500;
             }
         }
 }

If you would like to visualize it here is what the above code creates in openGL:
http://img580.imageshack.us/img580/5232/testdrawing.jpg
The first green square(ish) shape is what should be matched, but it matches the entire frame.
I get (50, 50) and (50, 478) for output.

So in summary, the function needs a way to break out of the loop, I'm just not sure what the condition should be.

And thanks again for your help and time.

Edit: I didn't get correct output even with one rectangle to search for. Top and left seem to be correct with one rectangle in the haystack but are wrong when there is more than one.
Last edited on
Topic archived. No new replies allowed.