2 Star 2 Fork 2

李志强/handtrack

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
detecposition.cpp 5.87 KB
一键复制 编辑 原始数据 按行查看 历史
gikieng 提交于 2014-11-27 21:05 . 整理一下代码
#include "detecposition.h"
#include <iostream>
const int move4[4][2] = {0, 1, 0, -1, 1, 0, -1, 0};
/*深度搜索最大连通块
* 标记idx
*/
int
DetecPosition::backtrack(int x, int y, int idx)
{
data[x * width + y] = 255 - idx;
int ret = 1;
int nx, ny;
for(int i = 0; i < 4; i++)
{
nx = x + move4[i][0];
ny = y + move4[i][1];
if(nx < height && ny < width && nx >= 0 && ny >= 0 && data[nx*width + ny] == 255)
{
ret += backtrack(nx, ny, idx);
}
}
return ret;
}
/*
* 保留最大连通块
* 确定最大连通块的重心位置
*
*/
CvPoint
DetecPosition::Detect(IplImage *src, IplImage *dst)
{
assert(src->nChannels == dst->nChannels);
cvCopy(src, dst);
data = (uchar*)dst->imageData;
width = src->width;
height = src->height;
int idx = 0;
int mx = 0, mxidx;
uchar *p = data;
for(int i = 0; i < height; i++)
for(int j = 0; j < width; j++)
{
if(*p == 255) ++mx;
p++;
}
if(mx > (height * width) / 2) return cvPoint(-1, -1);
mx = 0;
for(int i = 10; i < height - 10; i++)
{
for(int j = 10; j < width - 10; j++)
{
if(data[i*width + j] == 255)
{cnt[idx] = backtrack(i, j, idx + 1);
if(mx < cnt[idx]){mx = cnt[idx]; mxidx = idx;}
if(idx == 254 || mx > width * height /3)
{
return cvPoint(-1, -1);
}
idx ++;
cnt[idx] = backtrack(i, j, idx + 1);
if(mx < cnt[idx]){mx = cnt[idx]; mxidx = idx;}
if(idx == 254 || mx > width * height /3)
{
return cvPoint(-1, -1);
}
idx ++;
}
}
}
if(mx < 18000) return cvPoint(-1, -1);
p = data;
long long ax, ay;
ax = ay = 0;
for(int i = 0; i < height; i++)
{
for(int j = 0; j < width; j++)
{
if(*p == 254 - mxidx) {
ax += i;
ay += j;
*p = 255;
}
else *p = 0;
p++;
}
}
ax /= mx;
ay /= mx;
return cvPoint(ax, ay);
}
/*
* 确定点在视角的位置
*/
uchar
detectCode(CvPoint point, int width, int height)
{
uchar code = 0;
if((point.x - 240) * (point.x - 240) + (point.y - 240) * (point.y - 240) < 3600)
return 4;
code |= 1&(point.x < point.y?1:0);
code<<=1;
code |= 1&(-point.x + 480 < point.y?1:0);
return code;
}
/*
* 自动阔值算法二值化
*
*/
int
otsu(IplImage *src, IplImage *dst)
{
int width = src->width;
int height = src->height;
IplImage *imgYCrCb = cvCreateImage(cvSize(width, height),
src->depth, src->nChannels);
cvCvtColor(src, imgYCrCb, CV_BGR2YCrCb);
cvSplit(imgYCrCb, 0, dst, 0, 0);
cvFlip(dst, dst, 1);
float p[256] = {0};
uchar *data = (uchar *)dst->imageData;
for(int i = 0; i < height; i++)
for(int j = 0; j < width; j++)
p[data[i*dst->widthStep + j]] ++;
float w0, w1, u0, u1, deltaMax, deltaTmp;
float w[256] = {0}, tmp[256] = {0};
w[0] = p[0];
for(int i = 1; i < 256; i++)
{
w[i] = p[i] + w[i-1];
tmp[i] = i * p[i] + tmp[i-1];
}
int threshold = 0;
for(int i = 0; i < 255; i++)
{
w0 = w[i];
w1 = w[255] - w[i];
u0 = tmp[i]/w[i];
u1 = (tmp[255] - tmp[i])/(w[255] - w[i]);
deltaTmp = w0 * w1 *(u0 - u1) * (u0 - u1);
if(deltaTmp > deltaMax)
{
deltaMax = deltaTmp;
threshold = i;
}
}
cvThreshold(dst, dst, threshold, 255, CV_THRESH_BINARY);
IplImage * temp = cvCreateImage(cvGetSize(dst), 8,1);
cvMorphologyEx(dst, dst, temp, NULL, CV_MOP_CLOSE, 1);
cvMorphologyEx(dst, dst, temp, NULL, CV_MOP_OPEN, 1);
cvReleaseImage(&temp);
cvReleaseImage(&imgYCrCb);
return threshold;
}
inline int suitPoint(int x, int goal, int flag)
{
if(flag)
{
if(x < goal)
x = goal;
}
else if(x > goal)
x = goal;
return x;
}
inline double distance(CvPoint a, CvPoint b)
{
return sqrt((a.x - b.x) * (a.x - b.x) + (a.y + b.y) * (a.y + b.y));
}
int findContours(IplImage *src)
{
IplImage *dst;
//src = cvLoadImage("pic.jpg", -1);
dst = cvCreateImage(cvGetSize(src), 8, 3);
CvMemStorage *storage = cvCreateMemStorage();
CvSeq *contour = NULL, *hull = NULL;
//find contours 8-connects or 4-connects
CvContourScanner scanner = cvStartFindContours(src, storage);
cvDrawContours(dst, contour, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0);
int fingerCount = 0;
while((contour = cvFindNextContour(scanner))!= NULL)
{
//set black background
cvDrawContours(dst, contour, CV_RGB(255, 0, 0), CV_RGB(0, 255, 0), 0);
hull = cvConvexHull2(contour, 0, CV_CLOCKWISE, 0);
// CvPoint pt0 = **(CvPoint**) cvGetSeqElem(hull, hull->total - 1);
// for(int i = 0; i < hull->total; ++i)
// {
// CvPoint pt1 = **(CvPoint**)cvGetSeqElem(hull, i);
// cvLine(dst, pt0, pt1, CV_RGB(0, 0, 255));
// pt0 = pt1;
// }
CvSeq *defect = cvConvexityDefects(contour, hull);
for(int i = 0; i < defect->total; ++i)
{
CvConvexityDefect df = *(CvConvexityDefect*)cvGetSeqElem(defect, i);
cvCircle(dst, *df.start, 2, CV_RGB(255, 255, 0), -1);
cvCircle(dst, *df.end, 2, CV_RGB(255, 255, 0), -1);
cvCircle(dst, *df.depth_point, 2, CV_RGB(0, 255, 255), -1);
if(df.depth >= 19)
fingerCount++;
}
cvShowImage("dst", dst);
//cvShowImage("src", src);
cvWaitKey(10);
cvReleaseImage(&dst);
}
return fingerCount;
}
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
C++
1
https://gitee.com/gikieng/handtrack.git
git@gitee.com:gikieng/handtrack.git
gikieng
handtrack
handtrack
master

搜索帮助

0d507c66 1850385 C8b1a773 1850385