2017-10-12 20 views
5

J'essaie d'utiliser la détection de ligne BoofCV avec l'exemple donné de the BoofCV Android Demo. Pour cela, j'ai copié les classes et tout mis en place avec l'API Camera d'Android. Bien que la démonstration utilise l'orientation Paysage, mon activité doit être en mode Portrait, mais lorsqu'elle est réglée, la caméra pivote de 90 ° vers la gauche. Lorsque j'essaie de régler la caméra en conséquence, rien ne se passe. J'utilisé:Pourquoi BoofCV fait-il constamment tourner l'aperçu de la caméra vers la gauche?

  • Camera.setDisplayOrientation(90)
  • Camera.setParameters("orientation", "portrait")

Après un certain temps je me suis dit que ce n'est pas dispositif lié (testé sur différents appareils et les niveaux d'API) et il n'a rien à faire avec l'API Camera aussi (depuis que j'ai réussi à l'obtenir en portrait quand je commente la fonction VideoProcessor.init()).

Après avoir essayé pendant un certain temps, je ne peux toujours pas comprendre pourquoi le VideoProcessor continue à tourner l'image vers la gauche ...

Voici mon code pour le VideoProcessor:

public class LineProcessor extends Thread implements VideoProcessing { 

    /** 
    * Lock for reading and writing images with processing and render 
    */ 
    private final Object lockGui = new Object(); 

    /** 
    * Lock used when converting the video stream. 
    */ 
    private final Object lockConvert = new Object(); 

    private Paint mPaint; 
    private ImageType<GrayU8> imageType; 
    private GrayU8 image; 
    private GrayU8 image2; 
    private volatile boolean requestStop = false; 
    private volatile boolean running = false; 
    private int outputWidth; 
    private int outputHeight; 
    private View view; 
    private Thread thread; 

    private DetectLine detector; 
    private FastQueue<LineSegment2D_F32> lines = new FastQueue<LineSegment2D_F32>(LineSegment2D_F32.class,true); 
    private Bitmap bitmap; 
    private byte[] storage; 

    private double scale; 
    private double tranX,tranY; 

    /** 
    * Creates a new Line Processor from a Line Detector 
    * @param detector the Line Detector Segment 
    */ 
    public LineProcessor(DetectLine detector) { 
     this.imageType = ImageType.single(GrayU8.class); 
     this.detector = detector; 

     mPaint = new Paint(); 
     mPaint.setColor(Color.RED); 
     mPaint.setStyle(Paint.Style.STROKE); 
     mPaint.setStrokeWidth(2.0f); 
    } 

    @Override 
    public void init(View view, Camera camera) { 
     synchronized (lockGui) { 
      this.view = view; 

      Camera.Size size = camera.getParameters().getPreviewSize(); 
      outputWidth = size.width; 
      outputHeight = size.height; 
      declareImages(size.width,size.height); 
     } 

     // start the thread for processing 
     running = true; 
     start(); 
    } 



    @Override 
    public void onDraw(Canvas canvas) { 
     synchronized (lockGui) { 
      // the process class could have been swapped 
      if(image == null) 
       return; 

      int w = view.getWidth(); 
      int h = view.getHeight(); 

      // fill the window and center it 
      double scaleX = w/(double)outputWidth; 
      double scaleY = h/(double)outputHeight; 

      scale = Math.min(scaleX,scaleY); 
      tranX = (w-scale*outputWidth)/2; 
      tranY = (h-scale*outputHeight)/2; 

      canvas.translate((float)tranX,(float)tranY); 
      canvas.scale((float)scale,(float)scale); 

      render(canvas, scale); 
     } 
    } 



    @Override 
    public void convertPreview(byte[] bytes, Camera camera) { 
     if(thread == null) 
      return; 

     synchronized (lockConvert) { 
      ConvertUtils.nv21ToGray(bytes, image.width, image.height, image); 

     } 
     // wake up the thread and tell it to do some processing 
     thread.interrupt(); 
    } 

    @Override 
    public void stopProcessing() { 
     if(thread == null) 
      return; 

     requestStop = true; 
     while(running) { 
      // wake the thread up if needed 
      thread.interrupt(); 
      try { 
       Thread.sleep(10); 
      } catch (InterruptedException e) {} 
     } 
    } 

    @Override 
    public void run() { 
     thread = Thread.currentThread(); 
     while(!requestStop) { 
      synchronized (thread) { 
       try { 
        wait(); 
        if(requestStop) 
         break; 
       } catch (InterruptedException e) {} 
      } 

      // swap gray buffers so that convertPreview is modifying the copy which is not in use 
      synchronized (lockConvert) { 
       GrayU8 tmp = image; 
       image = image2; 
       image2 = tmp; 
      } 

      process(image2); 

      view.postInvalidate(); 
     } 
     running = false; 
    } 

    /** 
    * Scaling applied to the drawing canvas 
    */ 
    public double getScale() { 
     return scale; 
    } 

    /** 
    * Translation x applied to the drawing canvas 
    */ 
    public double getTranX() { 
     return tranX; 
    } 

    /** 
    * Translation y applied to the drawing canvas 
    */ 
    public double getTranY() { 
     return tranY; 
    } 


    public void process(GrayU8 gray) { 

     if(detector != null) { 
      List<LineParametric2D_F32> found = detector.detect(gray); 

      synchronized (lockGui) { 
       ConvertUtils.grayToBitmap(gray,bitmap,storage); 
       lines.reset(); 
       for(LineParametric2D_F32 p : found) { 
        LineSegment2D_F32 ls = ConvertUtils.convert(p, gray.width,gray.height); 
        lines.grow().set(ls.a,ls.b); 
       } 
      } 

     } 
    } 

    protected void render(Canvas canvas, double imageToOutput) { 

     canvas.drawBitmap(bitmap,0,0,null); 

     for(LineSegment2D_F32 s : lines.toList()) { 
      canvas.drawLine(s.a.x,s.a.y,s.b.x,s.b.y,mPaint); 
     } 

} 

    protected void declareImages(int width , int height) { 
     image = imageType.createImage(width, height); 
     image2 = imageType.createImage(width, height); 

     bitmap = Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888); 
     storage = ConvertUtils.declareStorage(bitmap,storage); 
    } 
} 

la la classe I est étendue à partir de VideoProcessing.java

Est-ce que quelqu'un a déjà rencontré ce problème?

+3

Avez-vous essayé faire pivoter la toile en fonction de la rotation de la caméra? – noongiya95

+0

Ouais que c'est en fait la solution au problème ... BoofCV dessine ses trucs sur une nouvelle toile et pour quelque raison que ce soit la fait pivoter .... J'ai changé la fonction de processus pour ce que je vais poster dans la question originale maintenant bien! Merci beaucoup! – 1resu

Répondre

2

La solution est en train de changer la fonction render à ce qui suit:

protected void render(Canvas canvas, double imageToOutput) { 

     canvas.rotate(90, 640f/2, 480f/2); 
     canvas.scale(480f/640f, 640f/480f, 640f/2, 480f/2); 
     canvas.drawBitmap(bitmap,0,0,null); 

     for(LineSegment2D_F32 s : lines.toList()) { 
      canvas.drawLine(s.a.x,s.a.y,s.b.x,s.b.y,mPaint); 
     } 
} 

Je pensais que ce n'était pas la manière propre avant, mais il est en fait la seule façon de travailler ....