C++ 用于眼睛跟踪的虹膜到屏幕计算
我目前正在试验眼睛跟踪,我已经成功地使用OpenCV和轮廓以及Hough变换构建了一个虹膜跟踪算法。但下一步对我来说还不清楚。我想知道我所做的计算是否正确,是否可以将眼睛的中心移动到屏幕上。使用者的头部有一个固定的位置 我想要的是一个算法,可以在所有人的视线偏离路线的情况下工作。有没有角度计算?那么,当用户更多地向右看时,是线性的吗 我现在做的是: 首先,我让用户查看特定点,并使用RANSAC检测最接近屏幕位置的虹膜位置。我用屏幕和虹膜上的四个2D点来实现。我使用单应性来得到正确的计算C++ 用于眼睛跟踪的虹膜到屏幕计算,c++,opencv,computer-vision,opencv3.0,eye-tracking,C++,Opencv,Computer Vision,Opencv3.0,Eye Tracking,我目前正在试验眼睛跟踪,我已经成功地使用OpenCV和轮廓以及Hough变换构建了一个虹膜跟踪算法。但下一步对我来说还不清楚。我想知道我所做的计算是否正确,是否可以将眼睛的中心移动到屏幕上。使用者的头部有一个固定的位置 我想要的是一个算法,可以在所有人的视线偏离路线的情况下工作。有没有角度计算?那么,当用户更多地向右看时,是线性的吗 我现在做的是: 首先,我让用户查看特定点,并使用RANSAC检测最接近屏幕位置的虹膜位置。我用屏幕和虹膜上的四个2D点来实现。我使用单应性来得到正确的计算 voi
void gaussian_elimination(float *input, int n){
// ported to c from pseudocode in
// http://en.wikipedia.org/wiki/Gaussian_elimination
float * A = input;
int i = 0;
int j = 0;
int m = n-1;
while (i < m && j < n){
// Find pivot in column j, starting in row i:
int maxi = i;
for(int k = i+1; k<m; k++){
if(fabs(A[k*n+j]) > fabs(A[maxi*n+j])){
maxi = k;
}
}
if (A[maxi*n+j] != 0){
//swap rows i and maxi, but do not change the value of i
if(i!=maxi)
for(int k=0;k<n;k++){
float aux = A[i*n+k];
A[i*n+k]=A[maxi*n+k];
A[maxi*n+k]=aux;
}
//Now A[i,j] will contain the old value of A[maxi,j].
//divide each entry in row i by A[i,j]
float A_ij=A[i*n+j];
for(int k=0;k<n;k++){
A[i*n+k]/=A_ij;
}
//Now A[i,j] will have the value 1.
for(int u = i+1; u< m; u++){
//subtract A[u,j] * row i from row u
float A_uj = A[u*n+j];
for(int k=0;k<n;k++){
A[u*n+k]-=A_uj*A[i*n+k];
}
//Now A[u,j] will be 0, since A[u,j] - A[i,j] * A[u,j] = A[u,j] - 1 * A[u,j] = 0.
}
i++;
}
j++;
}
//back substitution
for(int i=m-2;i>=0;i--){
for(int j=i+1;j<n-1;j++){
A[i*n+m]-=A[i*n+j]*A[j*n+m];
//A[i*n+j]=0;
}
}
}
ofMatrix4x4 findHomography(ofPoint src[4], ofPoint dst[4]){
ofMatrix4x4 matrix;
// create the equation system to be solved
//
// from: Multiple View Geometry in Computer Vision 2ed
// Hartley R. and Zisserman A.
//
// x' = xH
// where H is the homography: a 3 by 3 matrix
// that transformed to inhomogeneous coordinates for each point
// gives the following equations for each point:
//
// x' * (h31*x + h32*y + h33) = h11*x + h12*y + h13
// y' * (h31*x + h32*y + h33) = h21*x + h22*y + h23
//
// as the homography is scale independent we can let h33 be 1 (indeed any of the terms)
// so for 4 points we have 8 equations for 8 terms to solve: h11 - h32
// after ordering the terms it gives the following matrix
// that can be solved with gaussian elimination:
float P[8][9]={
{-src[0].x, -src[0].y, -1, 0, 0, 0, src[0].x*dst[0].x, src[0].y*dst[0].x, -dst[0].x }, // h11
{ 0, 0, 0, -src[0].x, -src[0].y, -1, src[0].x*dst[0].y, src[0].y*dst[0].y, -dst[0].y }, // h12
{-src[1].x, -src[1].y, -1, 0, 0, 0, src[1].x*dst[1].x, src[1].y*dst[1].x, -dst[1].x }, // h13
{ 0, 0, 0, -src[1].x, -src[1].y, -1, src[1].x*dst[1].y, src[1].y*dst[1].y, -dst[1].y }, // h21
{-src[2].x, -src[2].y, -1, 0, 0, 0, src[2].x*dst[2].x, src[2].y*dst[2].x, -dst[2].x }, // h22
{ 0, 0, 0, -src[2].x, -src[2].y, -1, src[2].x*dst[2].y, src[2].y*dst[2].y, -dst[2].y }, // h23
{-src[3].x, -src[3].y, -1, 0, 0, 0, src[3].x*dst[3].x, src[3].y*dst[3].x, -dst[3].x }, // h31
{ 0, 0, 0, -src[3].x, -src[3].y, -1, src[3].x*dst[3].y, src[3].y*dst[3].y, -dst[3].y }, // h32
};
gaussian_elimination(&P[0][0],9);
matrix(0,0)=P[0][8];
matrix(0,1)=P[1][8];
matrix(0,2)=0;
matrix(0,3)=P[2][8];
matrix(1,0)=P[3][8];
matrix(1,1)=P[4][8];
matrix(1,2)=0;
matrix(1,3)=P[5][8];
matrix(2,0)=0;
matrix(2,1)=0;
matrix(2,2)=0;
matrix(2,3)=0;
matrix(3,0)=P[6][8];
matrix(3,1)=P[7][8];
matrix(3,2)=0;
matrix(3,3)=1;
return matrix;
void gaussian_消除(浮点*输入,整数n){
//从中的伪代码移植到c
// http://en.wikipedia.org/wiki/Gaussian_elimination
浮点*A=输入;
int i=0;
int j=0;
int m=n-1;
而(i 对于(int k=0;k,您应该看看现有的解决方案:
- 用于用眼睛绘画的Eye writer(我测试它只是为了控制鼠标)
- 眼状瞳孔跟踪
(这里讨论的算法与您想要的类似)
祝你好运!也许这对你有帮助,祝你好运
cv::Mat computeMatXGradient(const cv::Mat &mat) {
cv::Mat out(mat.rows,mat.cols,CV_64F);
for (int y = 0; y < mat.rows; ++y) {
const uchar *Mr = mat.ptr<uchar>(y);
double *Or = out.ptr<double>(y);
Or[0] = Mr[1] - Mr[0];
for (int x = 1; x < mat.cols - 1; ++x) {
Or[x] = (Mr[x+1] - Mr[x-1])/2.0;
}
Or[mat.cols-1] = Mr[mat.cols-1] - Mr[mat.cols-2];
}
return out;
}
cv::Mat computeMatXGradient(常数cv::Mat&Mat){
cv::垫出(垫行、垫列、cv_64F);
对于(int y=0;y
你可以使用两只眼睛,还是必须支持斜视?我目前使用这个版本只跟踪一只眼睛。我的目标是与屏幕按钮交互,因此我将眼睛用作光标。好吧,这个注释比整个问题更具体,现在我们知道你想要什么了。它可能会稍微复杂一点。a b对你的设置进行更好的解释可能会更有帮助,因为这个问题可以通过多种方式解决。你的相机和电脑是如何配置的?你使用的是笔记本电脑的固定摄像头吗?不,是覆盆子Pi与黑色摄像头板-红外感光摄像头相结合。摄像头放在固定位置上。屏幕是从固定位置,to避免从虹膜到屏幕的复杂计算。从屏幕到用户的距离约为半米。尝试编辑代码,但括号似乎有问题。查看第19行、第53行和最后一行。我不想亲自编辑,以免弄糟。