0

I did adaptive thresholding with java OpenCV to identify the black dot which is in the image. However I failed to do that.My codes are as follows.Have to detect the black dot in the image When I was following the code which I wrote in here, the code unable to detect the black dot.The output image which is generated from this can be shown as follows. However this is not the image that I need

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Samarasinghe
 */
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferByte;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import javax.imageio.ImageIO;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfPoint;
import org.opencv.core.Point;
import org.opencv.core.Rect;
import org.opencv.core.Scalar;
import org.opencv.imgcodecs.Imgcodecs;
import org.opencv.imgproc.Imgproc;

public class kkknewversionj extends javax.swing.JFrame {

    /**
     * Creates new form kkknewversionj
     */
    double sum =0;
    public kkknewversionj() {
        initComponents();
    }
    public double imageprocessing1(){
        try{
            System.loadLibrary( Core.NATIVE_LIBRARY_NAME);
            //BufferedImage image= ImageIO.read(new File("C:\\Users\\My Kindom\\Desktop\\printscreen.JPG"));
            BufferedImage image= ImageIO.read(new File("C:\\Users\\Samarasinghe\\Downloads\\IS_11.jpg"));      
            byte[] data =((DataBufferByte) image.getRaster().getDataBuffer()).getData();
                    Mat mat = new Mat(image.getHeight(),image.getWidth(), CvType.CV_8UC3);
                    mat.put(0, 0, data);

                    Mat mat1 = new Mat(image.getHeight(), image.getWidth(), CvType.CV_8UC3);
                    Imgproc.cvtColor(mat, mat1, Imgproc.COLOR_RGB2GRAY);

                    byte[] data1 = new byte[mat1.rows()*mat1.cols()*(int)(mat1.elemSize())];
                    mat1.get(0, 0, data1);
                    BufferedImage image1 = new BufferedImage(mat1.cols(), mat1.rows(),BufferedImage.TYPE_BYTE_GRAY);
                    image1.getRaster().setDataElements(0, 0, mat1.cols(), mat1.rows(), data1);

                    ImageIO.write(image1, "jpg", new File("C:\\Users\\Samarasinghe\\Desktop\\gray.jpg"));
                    Mat source = Imgcodecs.imread("C:\\Users\\Samarasinghe\\Desktop\\gray.jpg",Imgcodecs.CV_LOAD_IMAGE_GRAYSCALE);
                    Mat destination = new Mat(source.rows(),source.cols(),source.type());
                    destination = source;

                    Imgproc.adaptiveThreshold(source,destination,255,Imgproc.ADAPTIVE_THRESH_MEAN_C,Imgproc.THRESH_BINARY, 19,-9);
                    Imgcodecs.imwrite("C:\\Users\\Samarasinghe\\Desktop\\ThreshZero.jpg", destination);
                    List<MatOfPoint> contours= new ArrayList<>();
                    Mat hierarchy =new Mat();

                    Imgproc.findContours(destination, contours, hierarchy,Imgproc.RETR_EXTERNAL,Imgproc.CHAIN_APPROX_NONE);
                    //Mat mask= new Mat (image.getHeight(),image.getWidth(),CvType.CV_8UC3);
                    Imgcodecs.imwrite("C:\\Users\\Samarasinghe\\Desktop\\mask.jpg",destination);
                    //Imgproc.drawContours(mask, contours,NORMAL, white);
                    //Imgcodecs.imwrite("C:\\Users\\Samarasinghe\\Desktop\\mask.jpg",mask);

                    for(int j=0;j<contours.size();j++){

                          sum=sum+contours.size();
//                          double[] d= hierarchy.get(0, j);
//                          Rect rect = Imgproc.boundingRect(contours.get(j));
//                          Point pt1=new Point(rect.x,rect.y);
//                          Point pt2=new Point(rect.x+rect.width,rect.y+rect.height);
//                          Scalar  eder=new Scalar(0,255,0);
//                          Imgproc.rectangle(destination, pt1, pt2, eder,2);
//                          Mat contour = contours.get(j);
//                          double contourarea=Imgproc.contourArea(contour);
//                          sum = sum + contourarea;

                    }System.out.println("Sum"+sum);



        }catch(Exception e){

        }
        return sum ;

    };


    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    // <editor-fold defaultstate="collapsed" desc="Generated Code">                          
    private void initComponents() {

        jButton1 = new javax.swing.JButton();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jButton1.setText("jButton1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(302, Short.MAX_VALUE)
                .addComponent(jButton1)
                .addGap(25, 25, 25))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(89, 89, 89)
                .addComponent(jButton1)
                .addContainerGap(188, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {                                         
         imageprocessing1();
    }                                        

    /**
     * @param args the command line arguments
     */
    public static void main(String args[]) {
        /* Set the Nimbus look and feel */
        //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
        /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
         * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
         */
        try {
            for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
                if ("Nimbus".equals(info.getName())) {
                    javax.swing.UIManager.setLookAndFeel(info.getClassName());
                    break;
                }
            }
        } catch (ClassNotFoundException ex) {
            java.util.logging.Logger.getLogger(kkknewversionj.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (InstantiationException ex) {
            java.util.logging.Logger.getLogger(kkknewversionj.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (IllegalAccessException ex) {
            java.util.logging.Logger.getLogger(kkknewversionj.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        } catch (javax.swing.UnsupportedLookAndFeelException ex) {
            java.util.logging.Logger.getLogger(kkknewversionj.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
        }
        //</editor-fold>

        /* Create and display the form */
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                new kkknewversionj().setVisible(true);
            }
        });
    }

    // Variables declaration - do not modify                     
    private javax.swing.JButton jButton1;
    // End of variables declaration                   
}
  • 2
    Instead of trying adaptive threshold, you may try color segmentation. http://www.pyimagesearch.com/2014/08/04/opencv-python-color-detection/ – ZdaR Jan 10 '17 at 05:19
  • What do you mean by "fail to detect" ? Does it detect only part of the black spot ? Does it find the spot but with holes ? Does it also detect the blue lines ? Does it only detect the blue lines ? – Soltius Jan 10 '17 at 09:19
  • @Soltius It doesn't detect any of them.. – Krishan Kavinda Jan 10 '17 at 13:43

1 Answers1

2

Zdar is right in the comments, you should switch color representation. Here, you are thresholding on a graylevel, which in your case is not great since it is hard to distinguish between the blue line and black spot.

If you represent your image in another color system, for instance one which distinguishes better between "saturated" color and black like HSV, you can segment your black spot much easier.

Here is the result I got for the Value channel of an HSV representation of your image  the Value channel of an HSV representation of your image.

If you do not know about color spaces, you can check out the pretty complete Wikipedia article about it, for example : https://en.wikipedia.org/wiki/HSL_and_HSV (which explains why I am careful with the term "saturated")

Edit by Krishan : his HSV representation This is my HSV image when I conduct the colour segmentation

Community
  • 1
  • 1
Soltius
  • 2,162
  • 1
  • 16
  • 28
  • Did u threshold the image using upper and lower boundary? – Krishan Kavinda Jan 10 '17 at 14:38
  • The image in my post it **not** thresholded, it's just the representation in another system. A simple one-boundary threshold should be enough to find the spot afterwards. And sorry, I didn't code it in Python, just clicked a few buttons in ImageJ, but I'm sure there is a way to convert RGB to HSV or other in OpenCV ;) – Soltius Jan 10 '17 at 14:45
  • When I was doing the colour segmentation I used following values as lower and upper boundaries in HSV scale. Scalar lowerb=new Scalar (160,50,50); Scalar upperb=new Scalar (180,255,255); however still i don't have the image which I desired – Krishan Kavinda Jan 10 '17 at 14:52
  • What does your HSV image look like, with no thresholds applied ? Does the V channel look like the one in my post ? If so, you just need to threshold on V, something like : HSVimg=RGBtoHSV(RGBimg); Vchannel=HSV[3]; and boundary like [0,128] on this new image works for me. – Soltius Jan 10 '17 at 15:08
  • [0,128] means values for V?? and here i have uploaded my HSV image too – Krishan Kavinda Jan 10 '17 at 15:14
  • Thank you for the tip Soltius and Zdar. I got the desired image just now. – Krishan Kavinda Jan 10 '17 at 15:38