我正在编写一个使用opencv java库跟踪眼球运动的程序。这是我的算法 -
但执行速度非常慢。将图像从磁盘载入Mat需要100ms,每个图像处理需要600ms。这是我的代码 -
package sumit;
import org.opencv.core.Core;
import org.opencv.core.Mat;
import org.opencv.core.MatOfRect;
import org.opencv.core.Rect;
import org.opencv.imgcodecs.Imgcodecs; // imread, imwrite, etc
import org.opencv.objdetect.CascadeClassifier;
import org.opencv.videoio.VideoCapture;
public class FaceDetector {
static MatOfRect faceDetections;
static Mat image,full,face;
static char yyy;
static int gh,lop;
static boolean d=false;
static int width,height,white1,white2,white5,white6,
w1,w2,h1,h2;
static int left5;
static int[] buf1,buf2;
static CascadeClassifier faceDetector2;
static MatOfRect faceDetections7;
static double xl,xr,xle,xre,yl,yr,yle,yre;
static int[] xyz;
static byte[] byby,byby1,byby2,byby3;
public static void main(String[] args) throws InterruptedException {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
faceDetector2= new CascadeClassifier();
faceDetections7 = new MatOfRect();
int cal=0;
VideoCapture camera = new VideoCapture();
while(true)
{
if(!camera.isOpened()){
full = Imgcodecs.imread("sumit/sumit20 (3).jpg");
if(cal==1)full = Imgcodecs.imread("sumit/sumit55.jpg");
}
else {
camera.read(full);
}
if(cal==0)
{
cal=1;
headpose0();
}
else
{
headpose1();
}
//System.out.println(String.format("%s",toString(endTime - startTime)));
}
}
static int close(){
int xmx=0,xms=0;
Rect jio[]=faceDetections7.toArray();
for(int i=0;i<jio.length;i++)
{
if(jio[i].height>xms)
{
xmx=i;
xms=jio[i].height;
}
}
return xmx;
}
static void headpose0(){
faceDetector2.load("D:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml");
faceDetector2.detectMultiScale(full, faceDetections7);
if(faceDetections7.toArray().length>1)
{
face=new Mat(full,faceDetections7.toArray()[close()]);
}
else
{
face=new Mat(full,faceDetections7.toArray()[0]);
}
int face_width=face.width();
int face_height=face.height();
//Mat lefti=(yy=='l')?new Mat(image,faceDetections.toArray()[left5]):new Mat(image,faceDetections.toArray()[1-left5]);
faceDetector2.load("D:/opencv/sources/data/haarcascades/haarcascade_eye.xml");
faceDetector2.detectMultiScale(face, faceDetections7);
int xmx=0,xms=0,xms1=0,xmx1=1;
Rect jio1[]=faceDetections7.toArray();
if(jio1.length>2)
{
for(int i=0;i<jio1.length;i++)
{
if(jio1[i].height>xms)
{
xmx=i;
xms=jio1[i].height;
}
else if(jio1[i].height>xms1)
{
xmx1=i;
xms1=jio1[i].height;
}
}
}
int left=(jio1[xmx].x<jio1[xmx1].x)?xmx:xmx1;
int right=(left==xmx)?xmx1:xmx;
xl=((double)(jio1[left].x) )/((double) face_width);
xr=((double)(jio1[right].x)) / ((double) face_width);
xle=((double)(jio1[left].x+jio1[left].width) ) / ((double)face_width);
xre=((double)(jio1[right].x+jio1[right].width) )/((double) face_width);
yl=((double)jio1[left].y )/ ((double) face_height);
yr=((double)jio1[right].y ) / ((double)face_height);
yle=((double)(jio1[left].y+jio1[left].height) )/ ((double)face_height);
yre=((double)(jio1[right].y+jio1[right].height) )/((double) face_height);
Mat sy=new Mat(face,jio1[left]);
Mat sys=new Mat(face,jio1[right]);
buf1=buf(sy);
white1=white(buf1,1);
buf2=buf(sys);
white2=white(buf2,1);
System.out.println(white1 +"\t"+white2 );
if(lop==0)
{
lop=1;
xyx.main1(buf1,sy.width(),sys.height());
}
}
static void headpose1(){
faceDetector2.load("D:/opencv/sources/data/haarcascades/haarcascade_frontalface_default.xml");
faceDetector2.detectMultiScale(full, faceDetections7);
if(faceDetections7.toArray().length>1)
{
face=new Mat(full,faceDetections7.toArray()[close()]);
}
else
{
face=new Mat(full,faceDetections7.toArray()[0]);
}
int face_width=face.width();
int face_height=face.height();
//Mat lefti=(yy=='l')?new Mat(image,faceDetections.toArray()[left5]):new Mat(image,faceDetections.toArray()[1-left5]);
Mat cf=face.submat((int)(yl*face_height), (int)(yle*face_height),
(int)(xl*face_width),(int)( xle*face_width) ) ;
Mat cd=face.submat((int)(yr*face_height), (int)(yre*face_height),
(int)(xr*face_width),(int)( xre*face_width) );
buf1=buf(cf );
w1 =cf.width();
w2=cd.width();
h1 =cf.height();
h2=cd.height();
buf2=buf( cd );
white5=white(buf1,5);
white6=white(buf2,1);
System.out.println(white5 +"\t"+white6 );
if(!blink())
lefte('l');
}
//extract eye from image(yy=1(left) =0(right)
static void lefte(char yy)
{
yyy=yy;
if(yy=='l')
{
xyz=buf1;
width=w1;
height = h1;
}
else if(yy=='r')
{
xyz=buf2;
color(xyz);
width=w2;
height = h2;
}
joi();
int at=t1();
if(at==3)lefte('r');
else
{
xyx.main1(xyz,width,height);
line();
}
}
//converts mat to buffered image
static int[] buf(Mat image){
int index=0;
byte[] data = new byte[image.rows()*image.cols()*(int)(image.elemSize())];
int[] datax=new int [image.rows()*image.cols()*(int)(image.elemSize())];
image.get(0, 0, data);
for(int x:data){
datax[index]=x & 0xFF;
index++;
}
return datax;
}
//draws line where max red and blue >width/6
static void line(){
int limit0=(width*gh);
int limit1=(width*(gh-1));
for(int j=limit0;j<limit1;j++)
{
xyz[j+2]=0;
xyz[j+1]=255;
xyz[j]=0;
}
}
static int white(int[] buf1,int ert){
int ans=0;int max,min;
for(int j=0;j<buf1.length;j+=3)
{
max=Math.max (buf1[j], Math.max(buf1[j+1],buf1[j+2] ) );
min=Math.min (buf1[j], Math.min(buf1[j+1],buf1[j+2] ) );
if(min>110 && (max-min)<20 ){
if(ert==5)
{
buf1[j+2]=255;
buf1[j+1]=0;
buf1[j]=0;
}
ans++;
}
else if(ert==5){
if(min>80 && (max-min)<20 ){
buf1[j+2]=255;
buf1[j+1]=0;
buf1[j]=0;
}
else if(min<70 && (max-min)<20 )
{
buf1[j+2]=0;
buf1[j+1]=0;
buf1[j]=255;
}
}
}
return ans;
}
static void color(int[] tab){
int max;
int min;
for(int j=0;j<tab.length;j+=3)
{
max=Math.max (tab[j], Math.max(tab[j+1],tab[j+2] ) );
min=Math.min (tab[j], Math.min(tab[j+1],tab[j+2] ) );
if(min>80 && (max-min)<20 ){
tab[j+2]=255;
tab[j+1]=0;
tab[j]=0;
}
else if(min<70 && (max-min)<20 )
{
tab[j+2]=0;
tab[j+1]=0;
tab[j]=255;
}
}
}
static boolean blink(){
boolean xdx=false;
if ( (white5<(white1*0.6 ) ) && ( white6 < (white2*0.6)) )
{
System.out.println("bb");
// Serial(bb)
xdx=true;
}
else if (white5 < (white1*0.6) )
{
System.out.println("lb");
// Serial(lb)
xdx=true;
}
else if (white6 < (white2*0.6) )
{
System.out.println("rb");
// Serial(rb)
xdx=true;
}
return xdx;
}
//finds pos of eyeball
static int t1(){
int a1=0,a4=0,a3=0,a5=0,a6=0,a7=0;
int limit0=(width*gh);
int limit1=(width*(gh-1));
for (int i=limit0; i<limit1;i+=3)
{
if(xyz[i+2]==255 && xyz[i+1]==0 && xyz[i]==0)
{
a1++;
if(a3==0)
{
a3=1;
a6=i;
}
}
else
{
if (a1>a5)
{
a5=a1;
a7=i-1;
a4=a6;
}
a3=0;
a1=0;
}
}
int ix=0,bx=0;boolean left=false;
for(int i=(limit0+(a4*3));i>limit0;i-=3)
{
if(xyz[i]==255 && xyz[i+1]==0 && xyz[i+2]==0)
{
ix++;
}
}
for(int i=(limit0+(a7*3));i<limit1;i+=3)
{
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
bx++;
}
}
left = (ix>bx)?true:false;
String omi=null;
int l1,l2,l5,l6;
l1=l2=l5=l6=0;
int x1,x2,x4,x5,x6,x8;
x1=x2=x4=x5=x6=x8=0;
if(!left)
{
for(int i=(limit0+(a7*3));i<limit1;i+=3)
{
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
l1++;
}
if(xyz[i]==0 && xyz[i+2]==255 && xyz[i+1]==0)
{if(l1> (width/6.0) )
l2++;
}
}
if(l2< (width*0.05) )omi="right";
// if(l2>width/)
// if (a7<width*(3.5/8.0)) omi="centre";
//if (a7>=width/2.0) omi="right";
else
{
sumit1:
for (int i=(limit0+(a7*3));i<limit1;i+=3)
{
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
x5++;
}
if(x5 >width*(1.0/15.0) )
{
if(xyz[i]==0 && xyz[i+2]==255 && xyz[i+1]==0)
{
x1++;
x2=0;
if(x1> width*(1.0/60.0) )
{
x6=3;
x8=10;
}
}
else
{
x2++;
if(x2> width*(1.0/18.0) )
{
if(x6==3)break sumit1;
x1=0;
}
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
if(x8!=10) x8=7;
x4=0;
}
else
{
if(x8==7) x4++;
if(x4> width*(1.0/15.0) ) break sumit1;
}
}
}
if (x1> width*0.05) omi="centre";
if (x1< width*0.05 ) omi="right";
}
}
}
if(left)
{
if(yyy=='l')return 3;
for(int i=(limit0+(a4*3));i>limit0;i-=3)
{
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
l5++;
}
if(xyz[i]==0 && xyz[i+2]==255 && xyz[i+1]==0)
{if(l5> (width/6.0) )
l6++;
}
}
if(l6< (width*0.05) )omi="left";
// if(l2>width/)
// if (a7<width*(3.5/8.0)) omi="centre";
//if (a7>=width/2.0) omi="right";
else
{
x1=x2=x4=x5=x6=x8=0;
sumit:
for (int i=(limit0+(a7*3));i<limit1;i+=3)
{
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
x5++;
}
if(x5 >width*(1.0/15.0) )
{
if(xyz[i]==0 && xyz[i+2]==255 && xyz[i+1]==0)
{
x1++;
x2=0;
if(x1> width*(1.0/60.0) )
{
x6=3;
x8=10;
}
}
else
{
x2++;
if(x2> width*(1.0/18.0) )
{
if(x6==3)break sumit;
x1=0;
}
if(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0)
{
if(x8!=10) x8=7;
x4=0;
}
if(!(xyz[i+2]==0 && xyz[i]==255 && xyz[i+1]==0))
{
if(x8==7) x4++;
if(x4>width*(1.0/15.0) ) break sumit;
}
}
}
if (x1> width*0.05 )omi="centre";
if (x1< width*0.05 )omi="right";
}
}
}
System.out.println(omi);
return 0;
}
//calculates line with max red and blue >width/6
static void joi(){
System.out.println(width/6);
int ko=0,koi=0,max=0,row=0,col=0;
for(int j=0;j<xyz.length;j+=3)
{
if(xyz[j+2]==255 && xyz[j+1]==0 && xyz[j]==0)
ko++;
else if(xyz[j+2]==0 && xyz[j+1]==0 && xyz[j]==255)
koi++;
col++;
if(col==width){
//System.out.println(koi);
if(ko>max && koi > width/6.0)
{
max=ko;
gh=row;
}
row++;
ko=0;koi=0;
}
}
}
}
如何提高程序速度?也是,这更快 -
从mat中提取每个像素并处理
将mat转换为byte []并从byte []和process
中提取r,g,b值1最后一个问题 - Mat.get(0,0,byte [])是否以r,g,b或b,g,r顺序存储像素(在byte []中)?