954,176 Members — Technology Publication meets Social Media
Username:
Password:
Lost login information?
Have something to say? Contribute New Article Reply to this Article

Comparing Images For Similarity

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++

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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.

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

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....

tonakai
Junior Poster
121 posts since Feb 2005
Reputation Points: 25
Solved Threads: 11
 

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.

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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

tonakai
Junior Poster
121 posts since Feb 2005
Reputation Points: 25
Solved Threads: 11
 

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

Thanks again.

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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()

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

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.

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

unfortunately, pixel grabber never works.

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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.

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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 :)

tonakai
Junior Poster
121 posts since Feb 2005
Reputation Points: 25
Solved Threads: 11
 

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?

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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);
  }
}
Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

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

Ghost
Posting Whiz
352 posts since Aug 2004
Reputation Points: 12
Solved Threads: 2
 

Sorry, I really can't help much. I've never done this so I don't know much about it. I did a search through the java.sun.com forums and came up with this:

http://onesearch.sun.com/search/developers/index.jsp?charset=UTF-8&qt=compare+two+images&col=devforums

Check that out and see if you can find anythig

server_crash
Postaholic
2,111 posts since Jun 2004
Reputation Points: 113
Solved Threads: 20
 

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

tonakai
Junior Poster
121 posts since Feb 2005
Reputation Points: 25
Solved Threads: 11
 

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

sanjrockz
Newbie Poster
3 posts since Feb 2008
Reputation Points: 7
Solved Threads: 0
 

can image compare via PHP?

roti_john
Newbie Poster
4 posts since Oct 2009
Reputation Points: 10
Solved Threads: 0
 

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

BestJewSinceJC
Posting Maven
2,772 posts since Sep 2008
Reputation Points: 874
Solved Threads: 354
 

This article has been dead for over three months

Post: Markdown Syntax: Formatting Help
You