opencv java程序执行缓慢

时间:2015-05-14 02:07:03

标签: java arrays performance opencv image-processing

我正在编写一个使用opencv java库跟踪眼球运动的程序。这是我的算法 -

  1. 最初存储开放眼球的像素(原始图像)
  2. 使用haarcascade分类器检测眼球(在下一图像中)
  3. 算不了。白色像素并与原始图像进行比较,以确定是否关闭了眼睛
  4. 如果没有关闭,将mat转换为字节数组
  5. 从数组中提取每个像素的r,g,b值并处理以找到眼球相对于原始图像的相对位置
  6. 处理涉及计数否。白色像素左右眼球
  7. if(left px> right px)眼球是正确的,反之亦然。
  8. 但执行速度非常慢。将图像从磁盘载入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;
                }
    
            }   
    
        }    
    
    }
    

    如何提高程序速度?也是,这更快 -

    1. 从mat中提取每个像素并处理

    2. 将mat转换为byte []并从byte []和process

      中提取r,g,b值
    3. 1最后一个问题 - Mat.get(0,0,byte [])是否以r,g,b或b,g,r顺序存储像素(在byte []中)?

0 个答案:

没有答案