Hi,

I was wondering if there was a way to compare two images for similarity (i.e. checking to see if signature is same as signature on a credit card). Thankx in advanced.

--
C++

Recommended Answers

All 20 Replies

Basicly there's three steps:
> 1. convert the two images to an array of integer.
> 2. compare the two arrays.
> 3. then decide if they're a similar or not.

You convert the two images into an array by creating a PixelGrabber, and then getting the pixels. You can also store colors and compare to make it more accurate.


Now, you can try just comparing Image Objects, but I don't know how accurate that would be:

Image one = new Image(...);
Image two = new Image(...);
if(one.equals(two)){
//... true
}
else{
//false
}

I've never really done this, so I don't know how either approach will work out.

it is a very deep subject and hard one, and comparing pixel-by-pixel is a very slow approch, i suggest you searching "image processing"....
in GIMP's web site you can find source code of this program which is a very good image processing tool....

server_crash, i tried your second technique and it turns out the images are never the same. I'm going to try your first method. could you please go into a little more detail on the first method. specifically, what method in the pixel grabber class returns an array of ints. thanx.

tonakai, what exactly is gimp? I'm a little confused. thanx for trying to help.

I also have one more question:
How do you copy a pictre to the clipboard

Thanks for all your help. I really appreciate it.

gimp is a program like abode photoshop but it is free. and you can have the source code. they may also help you, because these guys are all interested in image processing.
you can also find ready to use image processing libraries, but i am not sure where to look. if you want next year i am going to have a course, so i can give more information :D

thanx. i edited my above post and added a few questions. could you help?

Thanks again.

I'm going somewhere right now, but I'll get back to you on the questions a little later...Hope you don't mind.

I think the method in pixel grabber is .grabPixels()

I dont think .grabPixels returns an array of ints. Second, just so you know, im trying to compare two signatures. they may be slightly different from each other.

thanx.

unfortunately, pixel grabber never works.

sorry for being vague. when i check if int array one = int array two, it always turns out false. when i check if pixelGrabber.grapPixels() == pixelGrabber.grabPixels() it's always true.

any suggestions ??????????
thanx.

well, here a simple solution, if you want similarity then you need some threshold value. for example 10. when you grab a pixel, check if it is in the range of n-10 and n+10. where n is the value of the pixel you grab. this way you can get similar colors. but for similar photos, it may not be a good solution, so try and see :)

That makes sense! Basically, i need to check if the pixel is within 10 pixels of the original. GREAT IDEA! Thanx so much! how exactly do i check pixel by pixel, though? Is there a certain class I need to use (i.e. PixelGrabber())?

THANK YOU SO MUCH!

One more question: How do you copy images to the clipboard?

i tried this method. one problem with my for loop. it goes by twos and stops at 69990 but never breaks and continues. here's my code.

thanx in advanced for the help.

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.event.*;
import java.io.*;
import java.net.*;
import images.*;
import java2d.*;
import javax.imageio.*;
import java.awt.geom.*;
import java.awt.image.*;

public class paint extends JFrame implements ActionListener
{
  private int pointCount = 0;
  private Point points[] = new Point[1000];
  private JButton btn = new JButton("Done Signing");
  public String name = "";
  private File file;
  private UIManager.LookAndFeelInfo looks[];
  private Image one;
  private Image two;
  public Toolkit tool;
  private PixelGrabber pg;
  private JButton compare = new JButton("Compare");
  private Graphics2D g2d;
  private JButton clear = new JButton("Clear Area");

  public paint()
  {
    super("Painter");

    try{
      looks = UIManager.getInstalledLookAndFeels();
      UIManager.setLookAndFeel(looks[2].getClassName());
      SwingUtilities.updateComponentTreeUI(this);
    }
    catch(Exception e)
    {
    }

    Panel p1 = new Panel();
    p1.add(clear);
    clear.addActionListener(this);
    p1.add(btn);
    p1.add(compare);
    compare.addActionListener(this);

    getContentPane().add(p1,
                         BorderLayout.SOUTH);
    btn.addActionListener(this);

    addMouseMotionListener(
     new MouseMotionAdapter() {
       public void mouseDragged(MouseEvent event)
       {
         if(pointCount < points.length)
         {
           points[pointCount] = event.getPoint();
           ++pointCount;
           repaint();
         }
       }
     }
    );

    setSize(500,150);
    setVisible(true);
  }

  public void actionPerformed(ActionEvent ae)
  {
    if(ae.getSource() == clear)
    {
      new paint();
      setVisible(false);
    }
    if(ae.getSource() == btn)
    {
      JFileChooser fileChooser = new JFileChooser();
      fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
      int result = fileChooser.showSaveDialog(this);
      file = fileChooser.getSelectedFile();
      if(file == null || file.getName().equals(""))
        JOptionPane.showMessageDialog(null,
                                      "Invalid File Name Selected",
                                      "Invalid File Name",
                                      JOptionPane.ERROR_MESSAGE);
      intoPic();
    }

    if(ae.getSource() == compare)
    {
      JOptionPane.showMessageDialog(null,
                                  "Choose the file path of the original signature.",
                                  "Enter File Path",
                                  JOptionPane.INFORMATION_MESSAGE);
      JFileChooser fileChooser2 = new JFileChooser();
      fileChooser2.setFileSelectionMode(JFileChooser.FILES_ONLY);
      int result2 = fileChooser2.showOpenDialog(this);
      File newF1 = fileChooser2.getSelectedFile();
      String orig = "";
      if(newF1 == null || newF1.equals(""))
        JOptionPane.showMessageDialog(null,
                                      "Invalid File Name Selected",
                                      "Invalid File Name",
                                      JOptionPane.ERROR_MESSAGE);
      else
        orig = newF1.toString();


      JOptionPane.showMessageDialog(null,
                                  "Choose the file path of the original signature that should be compared to the original.",
                                  "Enter File Path",
                                  JOptionPane.INFORMATION_MESSAGE);
      JFileChooser fileChooser3 = new JFileChooser();
      fileChooser3.setFileSelectionMode(JFileChooser.FILES_ONLY);
      int result3 = fileChooser3.showOpenDialog(this);
      File newF2 = fileChooser3.getSelectedFile();
      String comp = "";
      if (newF2 == null || newF2.equals(""))
        JOptionPane.showMessageDialog(null,
                                      "Invalid File Name Selected",
                                      "Invalid File Name",
                                      JOptionPane.ERROR_MESSAGE);
      else
        comp = newF1.toString();



      try{
        tool = Toolkit.getDefaultToolkit();
        one = tool.getImage(orig);
        two = tool.getImage(comp);
        int pixelsOne [] = new int[500*140];
        PixelGrabber pg=new PixelGrabber(one,0,0,500,140,pixelsOne,0,500);
        pg.grabPixels();

        int pixelsTwo [] = new int[500*140];
        PixelGrabber pg2=new PixelGrabber(two,0,0,500,140,pixelsTwo,0,500);
        pg2.grabPixels();

        boolean same = false;

        /*********************************\
        |*       PROBLEM FOR LOOP:       *|     
        \*********************************/

        for(int i = 0; i < 70000; i++)
        {
          int up [] = {i+1,i+2,i+3,i+4,i+5,i+6,i+7,i+8,i+9,i+10};
          int down [] = {i+1,i+2,i+3,i+4,i+5,i+6,i+7,i+8,i+9,i+10};
          System.out.println(i);

          if(pixelsOne[i++]==pixelsTwo[up[9]]||
             pixelsOne[i]==pixelsTwo[up[0]]||
             pixelsOne[i]==pixelsTwo[up[1]]||
             pixelsOne[i]==pixelsTwo[up[2]]||
             pixelsOne[i]==pixelsTwo[up[3]]||
             pixelsOne[i]==pixelsTwo[up[4]]||
             pixelsOne[i]==pixelsTwo[up[5]]||
             pixelsOne[i]==pixelsTwo[up[6]]||
             pixelsOne[i]==pixelsTwo[up[7]]||
             pixelsOne[i]==pixelsTwo[up[8]]||
             pixelsOne[i]==pixelsTwo[down[0]]||
             pixelsOne[i]==pixelsTwo[down[1]]||
             pixelsOne[i]==pixelsTwo[down[2]]||
             pixelsOne[i]==pixelsTwo[down[3]]||
             pixelsOne[i]==pixelsTwo[down[4]]||
             pixelsOne[i]==pixelsTwo[down[5]]||
             pixelsOne[i]==pixelsTwo[down[6]]||
             pixelsOne[i]==pixelsTwo[down[7]]||
             pixelsOne[i]==pixelsTwo[down[8]]||
             pixelsOne[i]==pixelsTwo[down[9]])
          {
            same = true;
          }
          else
          {
            same = false;
          }
          if(i>=69990)
          {
            break;
          }
        }

        if(same)
        {
          System.err.println("SAME!");
        }
        else
        {
          System.err.println("DIFFERENT");
        }

      }
      catch(Exception e3)
      {
      }

    }
  }

  private void intoPic()
  {
    RenderedImage rendImage = myCreateImage();
    try
    {
      ImageIO.write(rendImage, "png", file);
    }
    catch(Exception e1)
    {
    }
  }

  private RenderedImage myCreateImage() {
        int width = 500;
        int height = 140;

        BufferedImage bufferedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);

        g2d = bufferedImage.createGraphics();

        g2d.setColor(Color.white);
        g2d.fillRect(0, 0, width, height);
        g2d.setColor(Color.black);
        for(int i=0; i < points.length && points[i] != null; i++)
        {
          g2d.fillRect(points[i].x, points[i].y, 4, 4);
          g2d.fillOval(points[i].x, points[i].y, 5, 5);
        }

        g2d.dispose();

        return bufferedImage;
    }


  public void paint(Graphics g)
  {
    super.paint(g);
    for(int i=0; i < points.length && points[i] != null; i++)
    {
      g.fillRect(points[i].x, points[i].y, 4, 4);
      g.fillOval(points[i].x, points[i].y, 5, 5);
    }
  }
  public static void main(String [] args)
  {
    paint app = new paint();
    app.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  }
}

sorry to sound annoying, but i sorta need a solution asap

server_crash, wen i tried what you first said, it didn't work. any suggestions?

well, i look at your code a bit, from what i see you need a different approch, but since i am not very good at image processing i cannot guide you. :) sorry

good luck

This post lists a different approach to compare images for similarity with references to some original posts. Hope it will useful to you :-)

can image compare via PHP?

Wow. . seriously? Go to the php forum. Start a new thread. This thread was started in 2005.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.