• R/O
  • HTTP
  • SSH
  • HTTPS

NDNGestureVision: Commit

A utility class which tracks the movement of hands. The camera image is the input.
The output can be used for hand gesture analysis.


Commit MetaInfo

Revisión4c3b6090dc4dcdc87c090b1adf058c23585664b3 (tree)
Tiempo2013-07-28 23:13:39
Autortkawata <takuji.kawata@gmai...>
Commitertkawata

Log Message

[NDNGestureVision]
- Minor improvement for hand tracking.
- Minor code refactoring. Changed all tab spaces to space characters.

Cambiar Resumen

Diferencia incremental

--- a/ndngesturevision/ndngesturevision.cpp
+++ b/ndngesturevision/ndngesturevision.cpp
@@ -31,11 +31,11 @@
3131 NDNGestureVision::NDNGestureVision(int imageWidth, int imageHeight, int scanningStep, float minFlowThreshold, int numOfFlows)
3232 : m_imageWidth(imageWidth), m_imageHeight(imageHeight), m_scanningStep(scanningStep), m_numOfFlows(numOfFlows)
3333 {
34- assert(imageWidth > 0 && imageHeight > 0 && scanningStep > 0);
34+ assert(imageWidth > 0 && imageHeight > 0 && scanningStep > 0);
3535
36- m_scanningXMax = imageWidth / scanningStep;
37- m_scanningYMax = imageHeight / scanningStep;
38- m_mapSize = m_scanningXMax * m_scanningYMax;
36+ m_scanningXMax = imageWidth / scanningStep;
37+ m_scanningYMax = imageHeight / scanningStep;
38+ m_mapSize = m_scanningXMax * m_scanningYMax;
3939 m_map = cv::Mat(m_scanningYMax, m_scanningXMax, CV_8U);
4040 m_minFlowThresholdP2 = minFlowThreshold * minFlowThreshold;
4141 m_tempSortedFlowNums = new int[numOfFlows * 2];
@@ -65,13 +65,13 @@ NDNGestureVision::NDNGestureVision(int imageWidth, int imageHeight, int scanning
6565 NDNGestureVision::~NDNGestureVision()
6666 {
6767 if (m_tempSortedFlowNums)
68- {
69- delete [] m_tempSortedFlowNums;
70- }
71- if (m_tempSortedFlowExtents)
72- {
73- delete [] m_tempSortedFlowExtents;
74- }
68+ {
69+ delete [] m_tempSortedFlowNums;
70+ }
71+ if (m_tempSortedFlowExtents)
72+ {
73+ delete [] m_tempSortedFlowExtents;
74+ }
7575 }
7676
7777 const NDNGestureVision::FlowRegion* NDNGestureVision::getFlow(int index) const
@@ -89,7 +89,7 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
8989 cv::cvtColor(newImage, newGrayScaleImage, CV_BGR2GRAY);
9090
9191 if( m_prevGray.data )
92- {
92+ {
9393 /*-------------------
9494 * Find flow regions
9595 */
@@ -97,57 +97,57 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
9797 cv::calcOpticalFlowFarneback(m_prevGray, newGrayScaleImage, flowMat, 0.5, 3, 15, 3, 5, 1.2, 0);
9898 m_map = cv::Mat::zeros(m_map.size(),CV_8U);
9999
100- std::vector<FlowRegion> flowRegions;
101- FlowRegion dummy;
102- flowRegions.push_back(dummy);
100+ std::vector<FlowRegion> flowRegions;
101+ FlowRegion dummy;
102+ flowRegions.push_back(dummy);
103103
104- int nextRegionNum = 1;
105- for(int y = 0; y < m_scanningYMax; y++)
106- {
107- int x = 0;
104+ int nextRegionNum = 1;
105+ for(int y = 0; y < m_scanningYMax; y++)
106+ {
107+ int x = 0;
108108 while(x < m_scanningXMax)
109109 {
110110 const cv::Point2f& fxy = flowMat.at<cv::Point2f>(y * m_scanningStep, x * m_scanningStep);
111111
112112 if (fxy.x * fxy.x + fxy.y * fxy.y <= m_minFlowThresholdP2)
113- {
113+ {
114114 x++;
115- }
116- else
117- {
118- int extent = 1;
119- float dxTotal = fxy.x;
120- float dyTotal = fxy.y;
121- std::set<int> attachingRegions;
115+ }
116+ else
117+ {
118+ int extent = 1;
119+ float dxTotal = fxy.x;
120+ float dyTotal = fxy.y;
121+ std::set<int> attachingRegions;
122122 int upperY = y - 1;
123123 if (upperY >= 0)
124- {
124+ {
125125 if (m_map.at<uchar>(upperY, x) > 0)
126- {
126+ {
127127 attachingRegions.insert(m_map.at<uchar>(upperY,x));
128- }
129- }
130- int ry = y * m_scanningStep;
131- int sp = x;
132- int xp = x + 1;
128+ }
129+ }
130+ int ry = y * m_scanningStep;
131+ int sp = x;
132+ int xp = x + 1;
133133 int rx = xp * m_scanningStep;
134- while (xp < m_scanningXMax)
135- {
134+ while (xp < m_scanningXMax)
135+ {
136136 const cv::Point2f& rfxy = flowMat.at<cv::Point2f>(ry, rx);
137137 if (rfxy.dot(fxy) < 0 || rfxy.x * rfxy.x + rfxy.y * rfxy.y < m_minFlowThresholdP2)
138- break;
138+ break;
139139
140- dxTotal += rfxy.x;
141- dyTotal += rfxy.y;
142- extent++;
140+ dxTotal += rfxy.x;
141+ dyTotal += rfxy.y;
142+ extent++;
143143 if (upperY >= 0 && m_map.at<uchar>(upperY, xp) > 0)
144- {
144+ {
145145 attachingRegions.insert(m_map.at<uchar>(upperY, xp));
146- }
147- xp++;
146+ }
147+ xp++;
148148 rx += m_scanningStep;
149- }
150- int ep = xp;
149+ }
150+ int ep = xp;
151151
152152 cv::Point2f direction;
153153 direction.x = dxTotal / extent;
@@ -156,103 +156,103 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
156156 direction.x = direction.x / distance;
157157 direction.y = direction.y / distance;
158158
159- std::set<int>::iterator it = attachingRegions.begin();
160- int mapNum = 0;
161- float maxR = 0;
162- while(it != attachingRegions.end())
163- {
164- float r = flowRegions[*it].direction.dot(direction);
165- if (r > 0 && maxR < r)
166- {
167- maxR = r;
168- mapNum = *it;
169- }
170- ++it;
171- }
172-
173- int regionNum = 0;
174- if (maxR > 0)
175- {
176- regionNum = mapNum;
159+ std::set<int>::iterator it = attachingRegions.begin();
160+ int mapNum = 0;
161+ float maxR = 0;
162+ while(it != attachingRegions.end())
163+ {
164+ float r = flowRegions[*it].direction.dot(direction);
165+ if (r > 0 && maxR < r)
166+ {
167+ maxR = r;
168+ mapNum = *it;
169+ }
170+ ++it;
171+ }
172+
173+ int regionNum = 0;
174+ if (maxR > 0)
175+ {
176+ regionNum = mapNum;
177177 float rate = ((float)extent) / ((float)(flowRegions[regionNum].extent + extent));
178- direction.x = flowRegions[regionNum].direction.x * (1.0f - rate) + direction.x * rate;
179- direction.y = flowRegions[regionNum].direction.y * (1.0f - rate) + direction.y * rate;
180- float adj = 1.0f / sqrt(direction.x * direction.x + direction.y * direction.y);
181- flowRegions[regionNum].direction.x = direction.x * adj;
182- flowRegions[regionNum].direction.y = direction.y * adj;
183- flowRegions[regionNum].distance = flowRegions[regionNum].distance * (1.0f -rate) + distance * rate;
184- flowRegions[regionNum].extent = flowRegions[regionNum].extent + extent;
185- if (sp * m_scanningStep < flowRegions[regionNum].xmin)
186- {
187- flowRegions[regionNum].xmin = sp * m_scanningStep;
188- }
189- if (flowRegions[regionNum].xmax < (ep - 1) * m_scanningStep)
190- {
191- flowRegions[regionNum].xmax = (ep - 1) * m_scanningStep;
192- }
193- flowRegions[regionNum].ymax = y * m_scanningStep;
194- }
178+ direction.x = flowRegions[regionNum].direction.x * (1.0f - rate) + direction.x * rate;
179+ direction.y = flowRegions[regionNum].direction.y * (1.0f - rate) + direction.y * rate;
180+ float adj = 1.0f / sqrt(direction.x * direction.x + direction.y * direction.y);
181+ flowRegions[regionNum].direction.x = direction.x * adj;
182+ flowRegions[regionNum].direction.y = direction.y * adj;
183+ flowRegions[regionNum].distance = flowRegions[regionNum].distance * (1.0f -rate) + distance * rate;
184+ flowRegions[regionNum].extent = flowRegions[regionNum].extent + extent;
185+ if (sp * m_scanningStep < flowRegions[regionNum].xmin)
186+ {
187+ flowRegions[regionNum].xmin = sp * m_scanningStep;
188+ }
189+ if (flowRegions[regionNum].xmax < (ep - 1) * m_scanningStep)
190+ {
191+ flowRegions[regionNum].xmax = (ep - 1) * m_scanningStep;
192+ }
193+ flowRegions[regionNum].ymax = y * m_scanningStep;
194+ }
195195 else
196- {
197- FlowRegion flowRegion;
198- flowRegion.extent = extent;
199- flowRegion.direction = direction;
200- flowRegion.distance = distance;
201- flowRegion.xmin = sp * m_scanningStep;
202- flowRegion.xmax = (ep - 1) * m_scanningStep;
203- flowRegion.ymin = y * m_scanningStep;
204- flowRegion.ymax = flowRegion.ymin;
205-
206- flowRegions.push_back(flowRegion);
207- regionNum = nextRegionNum;
208- nextRegionNum++;
209-
210- assert(nextRegionNum == flowRegions.size());
211- }
196+ {
197+ FlowRegion flowRegion;
198+ flowRegion.extent = extent;
199+ flowRegion.direction = direction;
200+ flowRegion.distance = distance;
201+ flowRegion.xmin = sp * m_scanningStep;
202+ flowRegion.xmax = (ep - 1) * m_scanningStep;
203+ flowRegion.ymin = y * m_scanningStep;
204+ flowRegion.ymax = flowRegion.ymin;
205+
206+ flowRegions.push_back(flowRegion);
207+ regionNum = nextRegionNum;
208+ nextRegionNum++;
209+
210+ assert(nextRegionNum == flowRegions.size());
211+ }
212212
213213 for (int i = sp; i < ep; i++)
214- {
214+ {
215215 m_map.at<uchar>(y, i) = regionNum;
216- }
217- x = ep;
218- }
219- }
220- }
216+ }
217+ x = ep;
218+ }
219+ }
220+ }
221221
222- for (int i = 0; i < m_numOfFlows * 2; i++)
223- {
224- m_tempSortedFlowNums[i] = 0;
225- m_tempSortedFlowExtents[i] = 0;
226- }
222+ for (int i = 0; i < m_numOfFlows * 2; i++)
223+ {
224+ m_tempSortedFlowNums[i] = 0;
225+ m_tempSortedFlowExtents[i] = 0;
226+ }
227227
228- int sortedFlowSizeMax = nextRegionNum <= m_numOfFlows * 2 ? nextRegionNum - 1 : m_numOfFlows * 2;
228+ int sortedFlowSizeMax = nextRegionNum <= m_numOfFlows * 2 ? nextRegionNum - 1 : m_numOfFlows * 2;
229229
230230 /*-------------------
231231 * Sort flowRegions with its extents and put the region numbers into m_tempSortedFlowNums[], m_tempSortedFlowExtents[]
232232 * The size of the list is stored in sortedFlowSize.
233233 */
234- int cnt = 0;
235- for (int i = 1 ; i < nextRegionNum; i++)
236- {
234+ int cnt = 0;
235+ for (int i = 1 ; i < nextRegionNum; i++)
236+ {
237237 if (flowRegions[i].extent <= m_minExt)
238- continue;
238+ continue;
239239
240- for (int j = 0; j < sortedFlowSizeMax; j++)
241- {
240+ for (int j = 0; j < sortedFlowSizeMax; j++)
241+ {
242242 if (flowRegions[i].extent > m_tempSortedFlowExtents[j])
243- {
243+ {
244244 for (int k = sortedFlowSizeMax - 2; k >= j; k--)
245- {
246- m_tempSortedFlowNums[k + 1] = m_tempSortedFlowNums[k];
247- m_tempSortedFlowExtents[k + 1] = m_tempSortedFlowExtents[k];
248- }
249- m_tempSortedFlowNums[j] = i;
245+ {
246+ m_tempSortedFlowNums[k + 1] = m_tempSortedFlowNums[k];
247+ m_tempSortedFlowExtents[k + 1] = m_tempSortedFlowExtents[k];
248+ }
249+ m_tempSortedFlowNums[j] = i;
250250 m_tempSortedFlowExtents[j] = flowRegions[i].extent;
251- cnt++;
252- break;
253- }
254- }
255- }
251+ cnt++;
252+ break;
253+ }
254+ }
255+ }
256256 int sortedFlowSize = sortedFlowSizeMax < cnt ? sortedFlowSizeMax : cnt;
257257
258258 /*-------------------
@@ -323,14 +323,13 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
323323 if (dmin < range * range)
324324 {
325325 cv::Point2f direction = flowRegions[m_tempSortedFlowNums[idx]].direction;
326- if (abs(direction.x) < abs(direction.y))
327- {
326+
327+ if (direction.y != 0)
328328 expectedFlowDirectionY = direction.y < 0 ? -1 : 1;
329- }
330- else
331- {
329+
330+ if (direction.x != 0)
332331 expectedFlowDirectionX = direction.x < 0 ? -1 : 1;
333- }
332+
334333 focusedRegionMoving = true;
335334 }
336335 }
@@ -352,14 +351,14 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
352351 int ey = range - step;
353352
354353 if (expectedFlowDirectionX > 0)
355- sx /= 3;
354+ sx = 0;
356355 else if (expectedFlowDirectionX < 0)
357- ex /= 3;
356+ ex = 0;
358357
359358 if (expectedFlowDirectionY > 0)
360- sy /= 3;
359+ sy = 0;
361360 else if (expectedFlowDirectionY < 0)
362- ey /= 3;
361+ ey = 0;
363362
364363 for (int y = sy; y <= ey; y += step)
365364 {
@@ -642,7 +641,7 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
642641 stillPointCnt++;
643642 int d = calcColorDiff(m_backgroundImage.at<cv::Vec3b>(iy,ix), newImage.at<cv::Vec3b>(iy,ix));
644643 if (d > m_backgroundDiffThreshold)
645- {
644+ {
646645 stillPointChangedPCnt++;
647646 stillPointChangePSum += d;
648647 }
@@ -784,7 +783,7 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
784783 * Draw output mat
785784 */
786785 if (pGestureVisionDrawMat)
787- {
786+ {
788787 int xs = pGestureVisionDrawMat->size().width / 4;
789788 int ys = pGestureVisionDrawMat->size().height / 4;
790789
@@ -886,7 +885,7 @@ void NDNGestureVision::calculateFlow(const cv::Mat &newImage, cv::Mat *pGestureV
886885 }
887886 }
888887
889- newGrayScaleImage.copyTo(m_prevGray);
888+ newGrayScaleImage.copyTo(m_prevGray);
890889 }
891890
892891 cv::Rect NDNGestureVision::findFingures(CvSeq *contour, std::vector<cv::Point>& fingures)
Show on old repository browser