javaFX con opencv

Iniciado por HunterLuis, 26 Mayo 2015, 03:24 AM

0 Miembros y 1 Visitante están viendo este tema.

HunterLuis

Cuando ejecutan el programa Histogramas y modifican el tinte a izquierda o derecha cambia el color de la imagen como es de esperarse, pero, la imagen indexada en dos bits se ve alterada también, es decir, se ven más blancos o negros dependiendo del escalar que se sume a la matriz de tinta.


Se supone que la tinta no debería modificar los brillos o saturaciones, por lo tanto, ¿ porque sucede eso ?

¿ Que pasa si solo mezclamos dos canales brillo y saturación ?, ¿ es posible ?, si lo es enviar imágenes, si no lo es, ¿ como puedo hacer para obtener imágenes como si el canal H no existiera ?

Aca les dejo el codigo es Una aplicacion en javafx fxml:

Este es el FXMLHistograma (Vista):
------------------------------------------------------------------------------------------------
Código (xml) [Seleccionar]
<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.image.*?>
<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="768.0" prefWidth="1024.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="histograma.FXMLHistogramaController">
  <center>
     <HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
        <children>
           <VBox prefHeight="200.0" prefWidth="100.0">
              <children>
                 <Label text="Original" />
                 <ImageView fx:id="aquired" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Separator prefWidth="200.0" />
                 <ImageView fx:id="modified" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Separator prefWidth="200.0" />
                 <ImageView fx:id="indexed" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
              </children>
           </VBox>
           <VBox prefHeight="200.0" prefWidth="100.0">
              <children>
                 <Label text="HSV" />
                 <ImageView fx:id="h_channel" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Slider fx:id="slider_h" blockIncrement="5.0" majorTickUnit="50.0" max="127.0" min="-127.0" minorTickCount="1" onValueChange="#doRedraw" showTickLabels="true" showTickMarks="true" />
                 <ImageView fx:id="s_channel" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Slider fx:id="slider_s" blockIncrement="5.0" majorTickUnit="50.0" min="-100.0" minorTickCount="1" onValueChange="#doRedraw" showTickLabels="true" showTickMarks="true" />
                 <ImageView fx:id="v_channel" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Slider fx:id="slider_v" blockIncrement="5.0" majorTickUnit="50.0" min="-100.0" minorTickCount="1" onValueChange="#doRedraw" showTickLabels="true" showTickMarks="true" />
              </children>
           </VBox>
           <VBox prefHeight="200.0" prefWidth="100.0">
              <children>
                 <Label text="HISTOGRAMAS" />
                 <ImageView fx:id="histogram_h" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Separator prefWidth="200.0" />
                 <ImageView fx:id="histogram_s" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
                 <Separator prefWidth="200.0" />
                 <ImageView fx:id="histogram_v" fitHeight="200.0" fitWidth="320.0" pickOnBounds="true" preserveRatio="true" />
              </children>
           </VBox>
        </children>
     </HBox>
  </center>
  <bottom>
     <HBox prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
  </bottom>
</BorderPane>

-----------------------------------------------------------------------------------------------

(Controlador) FXMLHistogramaController:
-----------------------------------------------------------------------------------------------
Código (java) [Seleccionar]
package histograma;

import java.io.ByteArrayInputStream;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Slider;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfByte;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.highgui.Highgui;
import org.opencv.imgproc.Imgproc;

/**
* FXML Controller class
*
* @author eduardodisanti
*/
public class FXMLHistogramaController implements Initializable {

   public Scalar ROJO = new Scalar(0,0,255);
   public Scalar VERDE = new Scalar(0,255,0);
   public Scalar AZUL = new Scalar(255,0,0);
   public Scalar BLANCO = new Scalar(255,255,255);
   public Scalar NEGRO = new Scalar(0,0,0);
   @FXML
   private Slider slider_h;
   @FXML
   private Slider slider_s;
   @FXML
   private Slider slider_v;
   
   /**
    * Initializes the controller class.
    * @param url
    * @param rb
    */
   
   @FXML
   private ImageView aquired;
   @FXML
   private ImageView modified;
   @FXML
   private ImageView indexed;
   @FXML
   private ImageView h_channel;
   @FXML
   private ImageView s_channel;
   @FXML
   private ImageView v_channel;
   @FXML
   private ImageView histogram_h;
   @FXML
   private ImageView histogram_s;
   @FXML
   private ImageView histogram_v;

   
   @Override
   public void initialize(URL url, ResourceBundle rb) {
       
       System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
       
       redraw();
   }
   
   private Image convertirDeMat(Mat m, String type) {
       
       MatOfByte byteMat = new MatOfByte();
       
       Highgui.imencode(type, m, byteMat);
       Image img = new Image(new ByteArrayInputStream(byteMat.toArray()));
       
       return(img);
   }
   
   @FXML
   private void doRedraw() {
       
       redraw();
   }

   private void redraw() {
       
       int rango = 256;
       
       Mat aquired_mat;
       Mat modified_mat;
       Mat indexed_mat;
       Mat hsv_mat = new Mat();
       Mat h_channel_mat;
       Mat s_channel_mat;
       Mat v_channel_mat;
       Mat histogram_h_mat;
       Mat histogram_s_mat;
       Mat histogram_v_mat;
       
       aquired_mat = Highgui.imread("C:\\opencv\\opencv-2.4.8\\canarias-spill-aquired.png");
       if(!aquired_mat.empty()) {
         aquired.setImage(convertirDeMat(aquired_mat, ".png"));
         Imgproc.cvtColor(aquired_mat, hsv_mat, Imgproc.COLOR_BGR2HSV);
         
         
         List<Mat> hsv_channel = new ArrayList<>();
           Core.split(hsv_mat, hsv_channel);
           Mat ch_h = hsv_channel.get(0).clone();
           Mat ch_s = hsv_channel.get(1).clone();
           Mat ch_v = hsv_channel.get(2).clone();
           
           h_channel.setImage(convertirDeMat(ch_h, ".png"));
           s_channel.setImage(convertirDeMat(ch_s, ".png"));
           v_channel.setImage(convertirDeMat(ch_v, ".png"));
           
           ch_h = addScalarToMat(ch_h, slider_h.getValue());
           ch_s = addScalarToMat(ch_s, slider_s.getValue());
           ch_v = addScalarToMat(ch_v, slider_v.getValue());
           
           List<Mat> hue = new ArrayList<>();
           hue.add(ch_h);
           histogram_h_mat = compute_histogram(hue, 256, rango, false);                                    
           draw_histogram(histogram_h, histogram_h_mat, rango, VERDE);
           
           List<Mat> sat = new ArrayList<>();
           sat.add(ch_s);
           histogram_s_mat = compute_histogram(sat, 256, rango, false);                        
           draw_histogram(histogram_s, histogram_s_mat, rango, AZUL);
           
           List<Mat> par = new ArrayList<>();
           par.add(ch_v);
           histogram_v_mat = compute_histogram(par,256,rango,false);
           draw_histogram(histogram_v, histogram_v_mat,rango,BLANCO);
           
           modified_mat = new Mat(aquired_mat.rows(), aquired_mat.cols(), aquired_mat.type());
           
           hsv_channel.set(0, ch_h);
           hsv_channel.set(1, ch_s);
           hsv_channel.set(2, ch_v);
           
           Core.merge(hsv_channel, modified_mat);
           Imgproc.cvtColor( ch_s,  modified_mat, Imgproc.COLOR_HSV2BGR);
           modified.setImage(convertirDeMat(modified_mat, ".png"));
           
           Mat gray_mat = new Mat();
           Imgproc.cvtColor(modified_mat, gray_mat, Imgproc.COLOR_RGB2GRAY);
           indexed_mat = new Mat();
           Imgproc.threshold(gray_mat, indexed_mat, 127, 255, Imgproc.THRESH_BINARY);
           indexed.setImage(convertirDeMat(indexed_mat, ".png"));
       }  
       
   }
   private void draw_histogram(ImageView imview, Mat histogram_mat, int rango, Scalar color) {
       
       double maxval = compute_max_histogram_value(histogram_mat);
       double ancho = (float)imview.getFitWidth();
       double ancho_barra = (float)imview.getFitWidth() / (float)rango;
       double alto  = imview.getFitHeight();
       
       Mat histogram = new Mat((int)alto, (int)ancho, CvType.CV_32SC3, new Scalar(0,0,0));
       
       
       float x = 0;
       for(int i=0;i<rango;i++) {
           double[] y = histogram_mat.get(i, 0);
           
           double yy = alto - (alto * y[0] / maxval);
           Core.rectangle(histogram, new Point(x, alto), new Point(x + ancho_barra, yy), color, (int)ancho_barra);
           x+=ancho_barra;
       }        
       imview.setImage(convertirDeMat(histogram, ".png"));
   }
  private double compute_max_histogram_value(Mat mat) {
       
       double maxval = Double.MIN_VALUE;
       
       for(int i=0;i<mat.rows();i++) {
               if(mat.get(i, 0)[0]>maxval) {
                   maxval = mat.get(i, 0)[0];
               }
       }
       
       return(maxval);
  }
   private Mat compute_histogram(List<Mat> mat_list, int tamanio, int rango, boolean accumulate) {
       
       MatOfInt histSize = new MatOfInt(tamanio);
       final MatOfFloat histRange = new MatOfFloat(0f, rango);

       Mat histograma = new Mat();
       Imgproc.calcHist(mat_list, new MatOfInt(0),new Mat(), histograma, histSize, histRange, accumulate);
       
       return histograma;
   }
   private Mat addScalarToMat(Mat mat, double value) {
       
       Mat ret = mat.clone();
       
       for(int row = 0; row < mat.rows(); row++) {
           for(int col = 0; col < mat.cols(); col++) {
               double aval[] = mat.get(row, col);
               double newval = value + aval[0];
               if(newval>255) {
                   newval = 255;
               } else {
                   if(newval<0) {
                      newval = 0;
                 }
               }
               aval[0] = newval;
               ret.put(row, col, aval);
          }  
       }
       return(ret);
   }
}
------------------------------------------------------------------------------------------------
Y (el Modelo) Histograma:
------------------------------------------------------------------------------------------------
public class Histograma extends Application {
   
   @Override
   public void start(Stage stage) throws Exception {
       Parent root = FXMLLoader.load(getClass().getResource("FXMLHistograma.fxml"));
       
       Scene scene = new Scene(root);
       stage.setTitle("Escoger Histograma");
       stage.setScene(scene);
       stage.show();
   }

   /**
    * @param args the command line arguments
    */
   public static void main(String[] args) {
       launch(args);
   }
   
}

------------------------------------------------------------------------------------------------
Bueno chicos este es el codigo si hay alguna solocion para mis dudas porfavor no duden en responder gracias.

Mod: Los códigos deben ir en etiquetas GeSHi

HunterLuis

Me olvidaba pueden trabajar con cualquier imagen yo como se daran cuenta estoy trabajando con otra imagen.