I am developing a vb.net 2008 application that should verify one's fingerprint from the scanner and the one from the database.
When I input an ID it's returning the fingerprint of that person from the database. Then how do I compare the two fingerprints images, one from the scanner and the one in the picturebox?
I am using this code but it's not giving me results.
Sub compare_6()
Me.Cursor = Cursors.WaitCursor
Application.DoEvents()
' Get the threshold.
Dim threshold As Integer = Integer.Parse(txtThreshold.Text)
' Load the images.
Dim bm1 As Bitmap = PictureBox1.Image
Dim bm2 As Bitmap = PictureBox2.Image
' Make a difference image.
Dim wid As Integer = Math.Min(bm1.Width, bm2.Width)
Dim hgt As Integer = Math.Min(bm1.Height, bm2.Height)
Dim bm3 As New Bitmap(wid, hgt)
' Create the difference image.
Dim are_identical As Boolean = True
' Dim r1, g1, b1, r2, g2, b2, r3, g3, b3 As Integer
Dim color1, color2 As Color
Dim eq_color As Color = Color.White
Dim ne_color As Color = Color.Red
Dim dr, dg, db, diff As Integer
For x As Integer = 0 To wid - 1
For y As Integer = 0 To hgt - 1
color1 = bm1.GetPixel(x, y)
color2 = bm2.GetPixel(x, y)
dr = CInt(color1.R) - color2.R
dg = CInt(color1.G) - color2.G
db = CInt(color1.B) - color2.B
'
diff = dr * dr + dg * dg + db * db
If diff <= threshold Then
bm3.SetPixel(x, y, eq_color)
Else
bm3.SetPixel(x, y, ne_color)
are_identical = False
End If
Next y
Next x
' Display the result.
picResult.Image = bm3
Me.Cursor = Cursors.Default
If (bm1.Width <> bm2.Width) OrElse (bm1.Height <> bm2.Height) Then are_identical = False
If are_identical Then
MessageBox.Show("The images are identical")
Exit Sub
Else
MessageBox.Show("The images are different")
Exit Sub
End If
bm1.Dispose()
bm2.Dispose()
End Sub `
I will be grateful if any one helps me with this. Thanks for your attention.
You will never get identical images. You can't get 2 exact scans. There are 2 types of fingerprint verification.
Points, where you look for intersections of ridges in the fingerprint.
Pattern, where pattern recognition algorithms are used. This is a lot harder, but produces better results, especially with partial prints.
What you need to do is to forget about reinventing the wheel and to incorporate a 3rd party software module that will do the comparison and return the results to you.
Google fingerprint comparison software. There's 3.7 million results. Here's one that's written in C++, and includes the source code. Good luck.
Related
Basically, I'm trying to loop through every pixel of a picture and check it against every pixel of another image. The problem is that it seems to just do this very slowly (I can no longer interact with the opened window, and Debug.WriteLine works). I want to be sure this is the problem rather than there just being something wrong with my code.
monPic and crop are dimmed as bitmaps at the top of my code.
Private Sub BtnCheck_Click(sender As Object, e As EventArgs) Handles btnCheck.Click
monPic = New Bitmap("../../../../" & picNum & ".png")
crop = New Bitmap("../../../../mm.png")
For x As Integer = 0 To monPic.Width - 1
Debug.WriteLine("level 1")
For y As Integer = 0 To monPic.Height - 1
Debug.WriteLine("level 2")
If CInt(monPic.GetPixel(x, y).A) <> 0 Then
For x2 As Integer = 0 To crop.Width - 1
Debug.WriteLine("level 3")
For y2 As Integer = 0 To crop.Height - 1
Debug.WriteLine("level 4")
If monPic.GetPixel(x, y).R = crop.GetPixel(x2, y2).R And monPic.GetPixel(x, y).G = crop.GetPixel(x2, y2).G And monPic.GetPixel(x, y).B = crop.GetPixel(x2, y2).B Then matches += 1
Next y2
Next x2
End If
Next y
Next x
lblMatches.Text = CStr(matches)
End Sub
This works quickly. It requires
Imports System.Security.Cryptography
Convert the 2 bitmaps to Byte arrays then hash with Sha256. Compare the hash.
Adapted from https://www.codeproject.com/Articles/9299/Comparing-Images-using-GDI
Private Function Compare(bmp1 As Bitmap, bmp2 As Bitmap) As String
Dim result = "It's a match!"
If Not (bmp1.Size = bmp2.Size) Then
result = "It's not even the same size"
Else
Dim ic As New ImageConverter
Dim btImage1(0) As Byte
btImage1 = CType(ic.ConvertTo(bmp1, btImage1.GetType), Byte())
Dim btImage2(0) As Byte
btImage2 = CType(ic.ConvertTo(bmp2, btImage2.GetType), Byte())
Dim shaM As New SHA256Managed
Dim hash1 = shaM.ComputeHash(btImage1)
Dim hash2 = shaM.ComputeHash(btImage2)
Dim i As Integer = 0
Do While i < hash1.Length AndAlso i < hash2.Length AndAlso result = "It's a match!"
If hash1(i) <> hash2(i) Then
result = "The pixels don't match"
End If
i = (i + 1)
Loop
End If
Return result
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim png1 As New Bitmap(path1)
Dim png2 As New Bitmap(path2)
Dim message = Compare(png1, png2)
MessageBox.Show(message)
End Sub
Trying to find a way to automatically change the color of the labels (to green if higher and red if less) in a chart when the value of the record is more or less than the value of the previous record.
I have a code that works if the value to compare is hard wired but I need to have a dynamic option.
Please find below the issues I'm trying to fix in the current code:
1. Compare the label value to the previous value (first value is compared to 0, if zero then black, otherwise red)
2. Change the color to red (255,0,0) and green (0,176,80) - currently it uses a theme color (don't know how to use RGB code)
Sub LabelFontColor()
Dim ser As Series
Dim ser_vals As Variant
Dim num As Integer
Set ser = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(1)
ser_vals = ser.Values
For num = LBound(ser_vals) To UBound(ser_vals)
With ser.Points(num).DataLabel.Format.TextFrame2.TextRange.Font.Fill.ForeColor
If ser_vals(num) > 0.15 Then 'tried ser_vals(num-1) but it didn't work
.ObjectThemeColor = msoThemeColorAccent2
Else
.ObjectThemeColor = msoThemeColorAccent3
End If
End With
Next num
End Sub
The reason you can't do "- 1" is the first comparison has nothing lower than it. What you need is a separate variable for tracking the last value.
I also added the RGB color codes you wanted:
Public Sub LabelFontColor()
Dim ser As Series
Dim ser_vals As Variant
Dim num As Integer
Dim previousVal As Variant
Set ser = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(1)
ser_vals = ser.Values
previousVal = 0
For num = LBound(ser_vals) To UBound(ser_vals)
With ser.Points(num).DataLabel.Format.TextFrame2.TextRange.Font.Fill.ForeColor
If ser_vals(num) > previousVal Then 'tried ser_vals(num-1) but it didn't work
.RGB = RGB(0, 176, 80)
Else
.RGB = RGB(255, 0, 0)
End If
End With
previousVal = ser_vals(num)
Next num
End Sub
It looks like you were on the right track with -1 however it probably failed on the first row, try something like this:
Sub LabelFontColor()
Dim ser As Series
Dim ser_vals As Variant
Dim num As Integer
Set ser = ActiveSheet.ChartObjects(1).Chart.SeriesCollection(1)
ser_vals = ser.Values
For num = LBound(ser_vals) To UBound(ser_vals)
With ser.Points(num).DataLabel.Format.TextFrame2.TextRange.Font.Fill.ForeColor
If num > LBound(ser_vals) Then
If ser_vals(num) > ser_vals(num - 1) Then
.ObjectThemeColor = msoThemeColorAccent2
Else
.ObjectThemeColor = msoThemeColorAccent3
End If
Else
.ObjectThemeColor = msoThemeColorAccent3
End If
End With
Next num
End Sub
I'm working on Visual Inspection System. One of my key function is to compare an image captured with an image from a data base. The comparison would reveal missing parts or damaged part. I have tried using pixel comparison, but this method is not reliable as it needs exactly similar image captured every time. Is there a way to improve this function to be more versatile. In a way it has to detect the difference in image even if the image captured is slightly offset or rotated. Please guide me using VB.Net. Below is my current code.
Private Sub btnGo_Click(ByVal sender As System.Object, _
ByVal e As System.EventArgs) Handles btnGo.Click
Me.Cursor = Cursors.WaitCursor
Application.DoEvents()
' Load the images.
Dim bm1 As Bitmap = Image.FromFile("C:\Users\pnasguna\Desktop\A56.jpg")
Dim bm2 As Bitmap = Image.FromFile("C:\Users\pnasguna\Desktop\A54.jpg")
' Make a difference image.
Dim wid As Integer = Math.Min(bm1.Width, bm2.Width)
Dim hgt As Integer = Math.Min(bm1.Height, bm2.Height)
Dim bm3 As New Bitmap(wid, hgt)
' Create the difference image.
Dim are_identical As Boolean = True
Dim eq_color As Color = Color.White
Dim ne_color As Color = Color.Red
For x As Integer = 0 To wid - 1
For y As Integer = 0 To hgt - 1
If bm1.GetPixel(x, y).Equals(bm2.GetPixel(x,y)) Then
bm3.SetPixel(x, y, eq_color)
Else
bm3.SetPixel(x, y, ne_color)
are_identical = False
End If
Next y
Next x
' Display the result.
PictureBox1.Image = bm3
Me.Cursor = Cursors.Default
If (bm1.Width <> bm2.Width) OrElse (bm1.Height <> bm2.Height) Then are_identical =False
If are_identical Then
MessageBox.Show("The images are identical")
Else
MessageBox.Show("The images are different")
End If
bm1.Dispose()
bm2.Dispose()
End Sub
You could take the XnaFan ImageComparison library to inspectionate the sourcecode as an example for your needs
It reveals the difference between pixels and can compare images with a Similarity coefficient, I've write a basic example of both:
Imports XnaFan.ImageComparison
' ===================================================
' Get percentage difference value between two images:
' ===================================================
Dim img1 As Image = Image.FromFile("C:\Image1.jpg")
Dim img2 As Image = Image.FromFile("C:\Image2.jpg")
Dim PercentageDifference As Single =
ImageTool.PercentageDifference(img1:=img1, img2:=img2, threshold:=3)
MessageBox.Show(String.Format("Percentage Difference: {0}%",
CSng(PercentageDifference * 100I).ToString("n1")))
' ========================================
' Get difference image between two images:
' ========================================
Dim img1 As Image = Image.FromFile("C:\Image1.jpg")
Dim img2 As Image = Image.FromFile("C:\Image2.jpg")
Dim DifferenceBitmap As Bitmap =
ImageTool.GetDifferenceImage(img1:=img1,
img2:=img2,
adjustColorSchemeToMaxDifferenceFound:=True,
absoluteText:=False)
PictureBox1.Image = DifferenceBitmap
If you want something more complex you could use AForge (Imaging) library to do the similarity comparison
Is there any way to attribute a code for every color, and be able to read them? Programatically I mean.
My target is to convert an image into code, then convert it back to image.
Each color has 4 fields (For some images, you only have 3 fields with meaningful information)
These fields include:
Alpha (A) (This represents opacity of the pixel)
Red (R) (Red intensity)
Green (G) (Green intensity)
Blue (B) (Blue intensity)
What you would do is read them and generate a code string for each one by concatenating the values to one another.
This can most likely be considered pseudo-code as I did not check if it compiles, but you should be doing something along the lines of this.
Dim pixelColor As Color
Dim image As BitMap = New BitMap("your_image.png")
Dim a As String
Dim r As String
Dim b As String
Dim g As String
Dim fileString As New StringBuilder()
fileString.AppendLine(image.Size.Width.ToString())
fileString.AppendLine(image.Size.Height.ToString())
' Loop over all pixels
For y As Integer = 0 To image.Size.Height - 1
For x As Integer = 0 To image.Size.Width - 1
pixelColor = image.GetPixel(x, y)
' get ARGB values as strings
a = pixelColor.A.ToString()
r = pixelColor.R.ToString()
g = pixelColor.G.ToString()
b = pixelColor.B.ToString()
' Append the colors, one pixel per line
fileString.AppendLine(a & " " & r & " " & g & " " & b)
Next
Next
Using file As New StreamWriter("image_data.txt")
outfile.Write(fileString.ToString())
End Using
Again, this probably doesn't compile. (I don't have a compiler with me at the moment)
edit:
I realized that the width and height need to be stored as well.
As for reading the file:
Dim file As System.IO.StreamReader
file = File.OpenText("text_file.txt")
Dim width As Integer = Convert.ToInt32(file.ReadLine)
Dim height As Integer = Convert.ToInt32(file.ReadLine)
Dim image As BitMap = New BitMap(width, height)
Dim currentX As Integer = 0
Dim currentY As Integer = 0
Do Until file.EndOfStream
Dim line As String = file.ReadLine
Dim valueArray(4) As String = line.Split(" ")
Dim a As Integer = Convert.ToInt16(valueArray(0))
Dim r As Integer = Convert.ToInt16(valueArray(1))
Dim g As Integer = Convert.ToInt16(valueArray(2))
Dim b As Integer = Convert.ToInt16(valueArray(3))
image.SetPixel(currentX, currentY, Color.FromArgb(a, r, g, b))
currentX = currentX + 1
If currentX == width Then
currentX = 0
currentY = currentY + 1
If currentY == height Then
Exit Do ' We're done here.
End If
End If
Loop
' At this point, you'll have a BitMap with all the pixels set.
Again, consider this pseudo-code.
each color is actually a ARGB color code just get integer value
Dim myColor As Color = Color.Red
Dim Code As Integer = myColor.ToArgb()
Dim myColorBack As Color = Color.FromArgb(Code)
I'm using this code to calculate the average color of an image but this is not working as desired. The result is inaccurate.
How to find the average color of the image ?
Private Sub btnAvg_Click() Handles btnAvg.Click
Dim x, y As Integer
bmp = New Bitmap(picBox.Tag.ToString)
For y = picBox.Top To picBox.Bottom
For x = picBox.Left To picBox.Right
With bmp.GetPixel(x, y)
totalR = totalR + .R : totalG = totalG + .G : totalB = totalB + .B
End With
Next x
Next y
avgR = totalR / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
avgG = totalG / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
avgB = totalB / ((picBox.Bottom - picBox.Top) * (picBox.Right - picBox.Left))
End Sub
I'm looking for a hi-speed, more than 80% accurate result. This is not a duplicate question as other questions deals with C# only
This should work:
Private Function getAverageColor(ByVal imageFilePath As String) As Color
Dim bmp As New Bitmap(imageFilePath)
Dim totalR As Integer = 0
Dim totalG As Integer = 0
Dim totalB As Integer = 0
For x As Integer = 0 To bmp.Width - 1
For y As Integer = 0 To bmp.Height - 1
Dim pixel As Color = bmp.GetPixel(x, y)
totalR += pixel.R
totalG += pixel.G
totalB += pixel.B
Next
Next
Dim totalPixels As Integer = bmp.Height * bmp.Width
Dim averageR As Integer = totalR \ totalPixels
Dim averageg As Integer = totalG \ totalPixels
Dim averageb As Integer = totalB \ totalPixels
Return Color.FromArgb(averageR, averageg, averageb)
End Function
Averaging colors doesn't make much sense in general. What's the average of hot pink and navy yellow? The way you are calculating it now produces a completely different color.
You'll need to work in a different color space. HSB is an easy one to work with and directly supported by the Color type. Albeit that it doesn't deal with the strongly non-linear color perception of the human eye. Color.GetHue() returns the hue, a value that's directly proportional to the color. You also ought to create a histogram so that the background of the photo doesn't disturb the results too much. Or at least work from the center of photo outwards. Whether that's good enough to detect skin color is fairly doubtful.
You could try this code and see if the results suit you. It reduces the image to a single pixel thumbnail:
Private Function getAverageColor(ByVal imageFilePath As String) As Color
Dim bmp As New Bitmap(imageFilePath)
Dim thumb As New Bitmap(bmp.GetThumbnailImage(1, 1, Nothing, IntPtr.Zero))
Return thumb.GetPixel(0, 0)
End Function