title: Tracking colored ball with Opencv Java
body: <p>This is my first time working with opencv. I choose it because I had experience coding with JAVA. But I have had some difficulties when trying to solve my coding problems.</p>
  
  <ol>
  <li>My first problem:</li>
  </ol>
  
  <p>I want to catch color from a frame so that when I click with my mouse it gives me RGB colors, which I can convert to HSV and send to my "inRange Method" and I can track any color I choose from my frame.
  It doesn't work. It gives me colors that have no relation with the color I selected.</p>
  
  <ol start="2">
  <li>My second problem:</li>
  </ol>
  
  <p>I want to detect the contour from my object and detect its position or its distance from the camera, but I'm not sure how.</p>
  
  <p>Here is my code:</p>
  
  <pre><code>package application;
  
  import java.awt.event.MouseEvent;
  import java.awt.image.BufferedImage;
  import java.io.ByteArrayInputStream;
  import java.util.ArrayList;
  import java.util.List;
  import java.util.Timer;
  import java.util.TimerTask;
  
  import javafx.application.Platform;
  import javafx.event.ActionEvent;
  import javafx.event.Event;
  import javafx.event.EventHandler;
  import javafx.event.EventType;
  import javafx.fxml.FXML;
  import javafx.scene.control.Button;
  import javafx.scene.control.Label;
  import javafx.scene.control.Slider;
  import javafx.scene.image.Image;
  import javafx.scene.image.ImageView;
  import javafx.scene.layout.Pane;
  import javafx.scene.paint.Color;
  
  import org.opencv.core.Core;
  import org.opencv.core.CvType;
  import org.opencv.core.Mat;
  import org.opencv.core.MatOfByte;
  import org.opencv.core.MatOfPoint;
  import org.opencv.core.Scalar;
  import org.opencv.core.Size;
  import org.opencv.highgui.Highgui;
  import org.opencv.highgui.VideoCapture;
  import org.opencv.imgproc.Imgproc;
  
  
  public class FxController 
  {
      double h=0,s=0,v=0,tolerance=10;
      @FXML 
      private Button start_b;
      @FXML 
      private ImageView currentFrame,currentFrame2;
      @FXML
      private Slider hSlider,sSlider,vSlider;
      @FXML
      private Label hLabel,sLabel,vLabel;
  
      private Pane rootElement;
      private Timer timer;
      private VideoCapture capture = new VideoCapture();
      private EventHandler handler;
      private  int red,green,bleu;
      private double alpha ;
  
      //private float hsb[];
       @FXML 
      protected void startCamera(ActionEvent event)
      {
          if(this.rootElement!=null)//savoir wache main class est accessible 
          {
              final ImageView frameView = currentFrame;//prendre l'objet ImageView pour montre le streaming
              final ImageView frameView2 = currentFrame2;
              /*handler = new EventHandler(){//clic dial la souris wesst l'image
  
  
                  @Override
                  public void handle(Event e) {
                      System.out.println("YOOOOO"+e.getEventType());
  
  
                  }
              };*/
              frameView.setOnMouseClicked(Event-&gt;{Mat m= new Mat();
                                                      byte[] pixel=new byte[4];
                                                      //int [] rgb = new int[3];
                                                      float[] hsv = new float[3];
                                                      //Imgproc.cvtColor(grabMat(0),m,CvType.CV_8UC1);
                                                      grabMat(0).convertTo(m, CvType.CV_8UC3);
                                                      m.get((int)Event.getX(),(int)Event.getY(),pixel);
                                                      /*alpha=(pixel[0] &gt;&gt; 24) &amp; 0xff;
                                                      red=(pixel[1] &gt;&gt; 16) &amp; 0xff;
                                                      green=(pixel[2] &gt;&gt; 8) &amp; 0xff;
                                                      bleu=(pixel[3]) &amp; 0xff;*/
                                                      alpha=pixel[0] &amp; 0xff;
                                                      red=pixel[1] &amp; 0xff;
                                                      green=pixel[2] &amp; 0xff;//fuuuuuuuuuuuuuuuuuuuuuck 
                                                      bleu=pixel[3] &amp; 0xff;
                                                      hsv=java.awt.Color.RGBtoHSB(red,green,bleu, null);
                                                      System.out.println("alpha= "+alpha+"---red= "+red+"---bleu= "+bleu+"---green= "+green);
                                                      h= hsv[0];
                                                      s=hsv[1];
                                                      v=hsv[2];
                                                      System.out.println("h= "+h+"---s= "+s+"---v= "+v);
                                                      //Event.getX();//x du pixel ou la souris berkat
                                                      //Event.getY();
                                                      //BufferedImage.setRGB(Event.getX(),Event.getY(), Color.getRGB());
                                                      });
  
              if(!this.capture.isOpened())//voir est c que la capture stream est ouverte
              {
                  this.capture.open(0);//commence la capture video 
                  //prendre le fram chaque 33 ms(30 frames/sec)
                  TimerTask FrameGrabber = new TimerTask(){
                      @Override 
                      public void run()
                      {
                          Image tmp = grabFrame(Imgproc.COLOR_RGB2RGBA);//imageRGB
                          //Image tmp2 = grabFrame(Imgproc.COLOR_RGB2HSV);
                          Image tmp3 = newColorDetection(grabMat(Imgproc.COLOR_BGR2HSV));
                          Platform.runLater(new Runnable(){
                              @Override 
                              public void run()
                              {
                                  frameView.setImage(tmp);
  
                                  frameView2.setImage(tmp3);
                              }
                          });
                      }
                  };
                  this.timer = new Timer();
                  this.timer.schedule(FrameGrabber,0,33);
                  this.start_b.setText("Stop Camera");
                  }
              else 
              {
                  this.start_b.setText("Start Camera");
                  //arrete le timer
                  if(this.timer!=null)
                  {
                      this.timer.cancel();
                      this.timer = null;
                  }
                  //realease camera
                  this.capture.release();
                  //efface le contenaire d'image 
                  frameView.setImage(null);
                  frameView2.setImage(null);
              }
  
          }
      }
  
  
  
      private Image grabFrame(int img)
      {
          Image imageToShow =null;//init
          Mat frame = new Mat();// cree une matrice
          //checker si la capture est ouverte
          if(this.capture.isOpened())
          {
              try{
                  this.capture.read(frame);//lire le frame courant
                  //test si le frame est vide
                  if(!frame.empty())
                  {
                      //convertire l'image au gris
                      Imgproc.cvtColor(frame, frame,img);
                      //convertir la Mat (objet) a Image (javaFx)
                      imageToShow = mat2Image(frame);
                  }
              }catch(Exception e){System.err.println("ERROR: "+e.getMessage());}
          }
          return imageToShow;
  
      }
      private Mat grabMat(int img)
      {
          Image imageToShow =null;//init
          Mat frame = new Mat();// cree une matrice
          //checker si la capture est ouverte
          if(this.capture.isOpened())
          {
              try{
                  this.capture.read(frame);//lire le frame courant
                  //test si le frame est vide
                  if(!frame.empty())
                  {
                      //convertire l'image au gris
                      Imgproc.cvtColor(frame, frame,img);
                      //convertir la Mat (objet) a Image (javaFx)
  
                  }
              }catch(Exception e){System.err.println("ERROR: "+e.getMessage());}
          }
  
          return frame;
  
      }
  
  
      private Image matToThresHolded(Mat frame)
      {   Image thresHoldedImg =null;
          Mat dFrame = new Mat();
          Imgproc.threshold(frame, dFrame, 127, 255,Imgproc.THRESH_TOZERO);
          thresHoldedImg=mat2Image(dFrame);
          return thresHoldedImg;
      }
      private Image mat2Image (Mat frame)
      {   //cree un buffer temporaire
          MatOfByte buffer = new MatOfByte();
          //encode le frame dans le buffer
          Highgui.imencode(".png",frame, buffer);
          //construire et retourne une image cree depuis l'image encode dans le buffer
          return new Image(new ByteArrayInputStream(buffer.toArray()));
  
      }
      public void setRootElement(Pane root)
      {
          this.rootElement = root;
      }
      public Image colorDetection(Mat hsvImage)
      {
          Image imageToShow=null;
          Mat threshedImg =new Mat();
          //Scalar hsvMin=new Scalar(106,60,90,0);//red
          //Scalar hsvMax=new Scalar(124,255,255,0);//red
          Scalar hsvMin=new Scalar(100,150,100);//bleu
          Scalar hsvMax=new Scalar(140,255,255);//bleu
      Core.inRange(hsvImage,hsvMin, hsvMax, threshedImg);
      imageToShow = mat2Image(threshedImg);
       return imageToShow;
      }
      public  Image newColorDetection(Mat hsv)
      {
  
          Image imageToShow=null;
          Mat threshedImg =new Mat(); 
          Mat threshedImg2 =new Mat();    
          Scalar hsvMin = new Scalar(0, 50, 50, 0);//red
          Scalar hsvMax = new Scalar(6, 255, 255, 0);//red
          Scalar hsvMin2 = new Scalar(175, 50, 50, 0);//red
          Scalar hsvMax2 = new Scalar(179, 255, 255, 0);//red
          //Scalar hsvMin=new Scalar(100,150,100);//bleu
          //Scalar hsvMax=new Scalar(140,255,255);//bleu
          //Scalar hsvMin=new Scalar(h-tolerance-1, s-tolerance, 0);//default
          //Scalar hsvMax=new Scalar(h+tolerance-1, s+tolerance,255);//default
       Core.inRange(hsv,hsvMin,hsvMax,threshedImg);
       Core.inRange(hsv, hsvMin2, hsvMax2, threshedImg2);
       Core.bitwise_or(threshedImg, threshedImg2, threshedImg);
      // dilate et erosion pour renforce l'image et supprime les pixels lmcheyrin 
      Mat dilate = Imgproc.getStructuringElement(Imgproc.MORPH_DILATE, new Size(3, 3));
          Imgproc.dilate(threshedImg, threshedImg, dilate);//dilate   
      Mat erode = Imgproc.getStructuringElement(Imgproc.MORPH_ERODE, new Size(3, 3));
          Imgproc.erode(threshedImg, threshedImg, erode);
          List&lt;MatOfPoint&gt; contours = new ArrayList&lt;MatOfPoint&gt;();    
          Imgproc.findContours(threshedImg, contours, new Mat(), Imgproc.RETR_LIST,Imgproc.CHAIN_APPROX_SIMPLE);
          imageToShow = mat2Image(threshedImg);
       return imageToShow;
  
      }
  }
  </code></pre>
  
  <p>My main </p>
  
  <pre><code>package application;
  
  import org.opencv.core.Core;
  
  import javafx.application.Application;
  import javafx.stage.Stage;
  import javafx.scene.Scene;
  import javafx.scene.layout.BorderPane;
  import javafx.fxml.FXMLLoader;
  
  public class Main extends Application {
      @Override
      public void start(Stage primaryStage) {
          try {
              FXMLLoader loader = new FXMLLoader(getClass().getResource("FristProjectFX.fxml"));
              BorderPane root = (BorderPane)loader.load();
              Scene scene = new Scene(root);
              scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
              primaryStage.setTitle("JavaFx YO!");
              primaryStage.setAlwaysOnTop(true);
              primaryStage.setScene(scene);
              primaryStage.show();//show GUI
              FxController controller = loader.getController();
              controller.setRootElement(root);
          } catch(Exception e) {
              e.printStackTrace();
          }
      }
  
      public static void main(String[] args) {
          System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
          launch(args);
      }
  }
  </code></pre>
  
  <p>here's what I got
  <img src="https://i.stack.imgur.com/atwNY.png" alt="enter image description here"> </p>
  
  <p>like what you see in the picture below when I click on the red zone I don't get red color CODE and even for other color .</p>
  
  <p>and My expectation is</p>
  
  <p><img src="https://i.stack.imgur.com/U8hxV.jpg" alt="enter image description here"></p>
  
  <p>like what you see on the picture I can catch the ball and the distance!</p>