EMGUCV facial recognition issue in VB.NET - vb.net

I'm trying to implement a web app with VB.NET which is supposed to perform facial recognition on images in a folder using EMGUCV library. Anyway, when I call method train on the facerecognizer object a strange exception is raised:
'OpenCV: 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows
Here's my test code:
Imports System.Drawing
Imports Emgu.CV
Imports Emgu.CV.Face
Imports Emgu.CV.Structure
Imports Emgu.CV.Util
Public Class _Default
Inherits Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
End Sub
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Dim images As New Mat
Dim Palb0 = "c://IMGDB//Alberto//0.jpg"
Dim Palb1 = "c://IMGDB//Alberto//1.jpg"
Dim Pcon0 = "c://IMGCONFRONTO//0.jpg"
images.PushBack(CvInvoke.Imread(Palb0, CvEnum.LoadImageType.Grayscale))
images.PushBack(CvInvoke.Imread(Palb1, CvEnum.LoadImageType.Grayscale))
Dim model = New EigenFaceRecognizer(80, Double.PositiveInfinity)
Dim labels As New VectorOfInt
Dim a(0) As Integer
a(0) = 0
labels.Push(a)
model.Train(images, labels)
Dim imgConf As Mat
imgConf = CvInvoke.Imread(Pcon0, CvEnum.LoadImageType.Grayscale)
model.Predict(imgConf)
Dim PR As FaceRecognizer.PredictionResult
Dim dst = PR.Distance
Dim lbl = PR.Label
MsgBox(dst)
End Sub
End Class
I tryed nearly everything but can' solve it. Any help will be really appreciated.

I managed to find a solution myself.
The roblem was really as simpe as the type of object I used for the constructor. It was supposed to be a VectorOfMat instead of Mat. the class couldn't work because it expected an array.
Dim images As New VectorOfMat
Another problem was in the constructor itself. It was supposed to be:
Dim model As New EigenFaceRecognizer(80, Double.PositiveInfinity)
One more piece of advice: If the train method doesen't receive an array of mat of at least two images, it will throw another exception. The images are supposed to be of the same size or (strange) the object will throw one more exception.
Finally the correct code for the predictionresult is:
Dim PR As FaceRecognizer.PredictionResult = model.Predict(imgConf)
and you get eigenfaces prediction distance:
Dim dis = PR.Distance
Hope this can get somebody out of trouble.
Ceers.

Related

vb.net winforms download without blocking

I'm downloading files .mp3 and my goal is not to have even a minimum GUI freezing during downloading.
My aim is also to display the bites received in a progress bar and through labels.
This code is working, but sometimes is freezing without any reason, sometimes the progress bar doesn't work until file is completely done.
So far, this is the "best" code I found online for a completely working progress bar during a download, but still gets problems.
How do you think I can increase performances? How can I make a resistant and reliable working progressbar? How can I download also large file without GUI freezing? I tried (curiosity) to download a 600 mb file and it completely freeze, not responding and not giving any issue back.
Thanks
EDIT1: I'm trying with this,eventhough I'm lost on high waves.. Any idea on how can I use this code and insert it into Jimi Answer? Answer
Imports System.IO
Imports System.IO.Path
Imports System.Net
Public Class Form1
Private downloader As MyDownloader = Nothing
Private Sub btnStartDownload_Click(sender As Object, e As EventArgs) Handles btnStartDownload.Click
Dim progress = New Progress(Of String)(
Sub(data)
MsgBox("we are on the UI thread here")
End Sub)
Dim url As Uri = New Uri(TextBox1.Text)
downloader = New MyDownloader()
'How can I remove this second? I don't need download from url every 1 second.
downloader.StartDownload(progress, url, 1)
End Sub
And
Imports System.ComponentModel
Imports System.Diagnostics
Imports System.Net
Imports System.Net.Http
Imports System.Text.RegularExpressions
Imports System.Threading
Public Class MyDownloader
Private Shared ReadOnly client As New HttpClient()
client.DownloadProgressChanged += AddressOf Client_DownloadProgressChanged
client.DownloadFileCompleted += AddressOf Client_DownloadFileCompleted
Private interval As Integer = 0
Private Sub Client_DownloadFileCompleted(ByVal sender As Object, ByVal e As AsyncCompletedEventArgs)
System.Windows.Forms.MessageBox.Show("Download OK!", "Message", MessageBoxButtons.OK, MessageBoxIcon.Information)
End Sub
Public Sub StartDownload(progress As IProgress(Of String), url As Uri, intervalSeconds As Integer)
interval = intervalSeconds * 1000
Task.Run(Function() DownloadAsync(progress, url))
End Sub
Private Sub Client_DownloadProgressChanged(ByVal sender As Object, ByVal e As DownloadProgressChangedEventArgs)
ProgressBar1.Minimum = 0
Dim receive As Double = Double.Parse(e.BytesReceived.ToString())
Dim total As Double = Double.Parse(e.TotalBytesToReceive.ToString())
Dim percentage As Double = receive / total * 100
label2.Text = $"{String.Format("{0:0.##}", percentage)}%"
ProgressBar1.Value = Integer.Parse(Math.Truncate(percentage).ToString())
End Sub
Private Async Function DownloadAsync(progress As IProgress(Of String), url As Uri) As Task
Dim pattern As String = "<(?:[^>=]|='[^']*'|=""[^""]*""|=[^'""][^\s>]*)*>"
Dim downloadTimeWatch As Stopwatch = New Stopwatch()
downloadTimeWatch.Start()
Do
Try
Dim response = Await client.GetAsync(url, HttpCompletionOption.ResponseContentRead)
Dim data = Await response.Content.ReadAsStringAsync()
data = WebUtility.HtmlDecode(Regex.Replace(data, pattern, ""))
progress.Report(data)
Dim delay = interval - CInt(downloadTimeWatch.ElapsedMilliseconds)
Await Task.Delay(If(delay <= 0, 10, delay))
downloadTimeWatch.Restart()
Catch ex As Exception
End Try
Loop
End Function
End Class
I'm Seriously lost on it, I tried to delete cancel download as I am not going to stop any download and I tried also to delete Download from url every 1 second as I just need one time download for every link.
Thanks

Capture still image from webcam (DirectSHowLib, VB.NET)

I'm ashamed, but I'll ask anyway: which is the most straightforward way to take a picture from a webcam with its default size and color-depth?
I started playing with DirectShowLib but I'm clueless... Can anyone guive me a guidance?
Imports DirectShowLib
Public Class Form1
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
PictureBox1.Image = Nothing
Dim Cam As DsDevice = DsDevice.GetDevicesOfCat(FilterCategory.VideoInputDevice).FirstOrDefault
If Cam IsNot Nothing Then
Stop
' ... what now?
End If
End Sub
End Class
DirectShowLib's samples DxSnap, DxWebCam (C#) show how to capture from a webcam. There is also VB.NET DxLogoVB there, it does a different thing but is still good if you also look for some DriectShow.NET + VB.NET sample code.
DxWebCam:
A poor man's web cam program. This application runs as a Win32 Service.
It takes the output of a capture graph, turns it into a stream of JPEG
files, and sends it thru TCP/IP to a client application.
DxSnap:
Use DirectShow to take snapshots from the Still pin of a capture
device. Note the MS encourages you to use WIA for this, but if
you want to do in with DirectShow and C#, here's how.
Note that this sample will only work with devices that output uncompressed
video as RBG24. This will include most webcams, but probably zero tv tuners.
Ok, the best I was able to do depends on AForge.Controls and AForge.Video.DirectShow and is working with this code, which I intend to improve (it is a rough scratch - but takes the picture):
Public Class Form1
Private Sub Test() Handles Me.Load
Dim rf As New RolleiFlex
PictureBox1.Image = rf.Click
End Sub
End Class
Public Class RolleiFlex
Public Sub New()
Dim vDevices = New AForge.Video.DirectShow.FilterInfoCollection(FilterCategory.VideoInputDevice)
Devices = vDevices.Cast(Of FilterInfo).Select(
Function(fi) New Device With {
.Name = fi.Name,
.MonikerString = fi.MonikerString}).ToArray
SelectedDevice = Devices.FirstOrDefault
vDevices = Nothing
End Sub
Public Devices As Device()
Public Property SelectedDevice As Device
Public Class Device
Public Property Name As String
Public Property MonikerString As String
End Class
Public Function Click() As Bitmap
Dim retBmp As Bitmap
Dim camera As New AForge.Controls.VideoSourcePlayer
camera.VideoSource = New VideoCaptureDevice(SelectedDevice.MonikerString)
camera.Start()
Do
retBmp = camera.GetCurrentVideoFrame
If retBmp Is Nothing Then Threading.Thread.Sleep(100)
Loop While retBmp Is Nothing
camera.Stop()
camera.Dispose()
camera = Nothing
Return retBmp
End Function
End Class

Trying to write IP address to textbox in Visual Basic

I am trying to write a simple program that finds the public IP for the computer it is being used on. However, I am not sure how to set the text of the TextBox to the IP address that is found. Can anyone help me?
Code:
Imports System.Net
Imports System.Text
Imports System.Text.RegularExpressions
Public Class Form1
Private Function GetMyIP() As IPAddress
Using wc As New WebClient
Return IPAddress.Parse(Encoding.ASCII.GetString(wc.DownloadData("http://tools.feron.it/php/ip.php")))
End Using
End Function
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
TextBox1.Text = (GetMyIP())
End Sub
Private Sub TextBox1_TextChanged(sender As Object, e As EventArgs)
End Sub
End Class
First, you should use Option Strict On. That would point out to you that you need to use
TextBox1.Text = GetMyIP().ToString()
Next, if you examine the headers from that web page you will see it returns the result in UTF-8 encoding, so you should use Encoding.UTF8 instead of Encoding.ASCII. Unfortunately, that still does not work - I will write more on that later.
However, WebClient has a DownloadString method which works well in this case:
Private Function GetMyIP() As IPAddress
Using wc As New WebClient
Dim url = "http://tools.feron.it/php/ip.php"
Dim x = wc.DownloadString(url)
Return IPAddress.Parse(x.Trim())
End Using
End Function
If you still want to use DownloadData, you should examine the returned bytes: you would find that the data you want is preceded by the bytes 0xEF 0xBB 0xBF. I do not know why. This is messing up the string that you want if you download it as an array of bytes.
You could use LINQ to remove the strange bytes:
Private Function GetMyIP() As IPAddress
Using wc As New WebClient
Dim url = "http://tools.feron.it/php/ip.php"
Dim x = wc.DownloadData(url)
Dim y = Encoding.UTF8.GetString(x.Where(Function(b) b < 128).ToArray())
Return IPAddress.Parse(y)
End Using
End Function
(I could have used Encoding.ASCII in there because the bytes over 127 have been removed.)

paypal API in VB.net

Hey all, i have converted some C# PayPal API Code over to VB.net. I have added that code to a class within my project but i can not seem to access it:
Imports System
Imports com.paypal.sdk.services
Imports com.paypal.sdk.profiles
Imports com.paypal.sdk.util
Namespace GenerateCodeNVP
Public Class GetTransactionDetails
Public Sub New()
End Sub
Public Function GetTransactionDetailsCode(ByVal transactionID As String) As String
Dim caller As New NVPCallerServices()
Dim profile As IAPIProfile = ProfileFactory.createSignatureAPIProfile()
profile.APIUsername = "xxx"
profile.APIPassword = "xxx"
profile.APISignature = "xxx"
profile.Environment = "sandbox"
caller.APIProfile = profile
Dim encoder As New NVPCodec()
encoder("VERSION") = "51.0"
encoder("METHOD") = "GetTransactionDetails"
encoder("TRANSACTIONID") = transactionID
Dim pStrrequestforNvp As String = encoder.Encode()
Dim pStresponsenvp As String = caller.[Call](pStrrequestforNvp)
Dim decoder As New NVPCodec()
decoder.Decode(pStresponsenvp)
Return decoder("ACK")
End Function
End Class
End Namespace
I am using this to access that class:
Private Sub cmdGetTransDetail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGetTransDetail.Click
Dim thereturn As String
thereturn =GetTransactionDetailsCode("test51322")
End Sub
But it keeps telling me:
Error 2 Name 'GetTransactionDetailsCode' is not declared.
I'm new at calling classes in VB.net so any help would be great! :o)
David
Solved
Dim payPalAPI As New GenerateCodeNVP.GetTransactionDetails
Dim theReturn As String
theReturn = payPalAPI.GetTransactionDetailsCode("test51322")
You're probably getting that error because you need to call it like this:
Private Sub cmdGetTransDetail_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdGetTransDetail.Click
Dim thereturn As String
Dim myTransaction as new GetTransactionDetails
thereturn = myTransaction.GetTransactionDetailsCode("test51322")
End Sub
Or you can make the function be a public shared function and access it as if it were a static method
Your GetTransactionDetailsCode method is an instance method of the GetTransactionDetails class, which means that you need an instance of the GetTransactionDetails class in order to call the method.
You can do that like this:
Dim instance As New GetTransactionDetails()
thereturn = instance.GetTransactionDetailsCode("test51322")
However, your method doesn't actually use the class instance, so you should change your GetTransactionDetails class to a Module instead.

Using .Net XmlSerialize for strings with embedded <cr><lf> loses <cr> when deserializing

The following (abysmal) code demonstrates how standard serialize/de-serialize in VB loses the CR when on de-serialize. This can be overcome by applying 'XmlAttribute(DataType:="string")' to Description. Why does it do this? I would like to fix this without applying a 'LF' -> 'CR''LF' in every affected class. This is fixing a bug in existing XML files generated without the XmlAttribute!
Imports System.Xml.Serialization
Imports System.Xml
Imports System.IO
Public Class Form1
Public Class MyObject
Public Description As String
End Class
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click
Dim x As New MyObject
x.Description = "Hello" + vbCrLf + "World"
Dim serializer As New XmlSerializer(GetType(MyObject))
Dim writer As StreamWriter = New StreamWriter("c:\temp\test.xml")
serializer.Serialize(writer, x)
writer.Close()
For i As Integer = 0 To x.Description.ToCharArray.Length - 1
Debug.Print(Asc(x.Description.ToCharArray(i, 1)))
Next
Debug.Print("**********************")
Dim reader As New StreamReader("c:\temp\test.xml")
Dim newObj As MyObject = CType(serializer.Deserialize(reader), MyObject)
For i As Integer = 0 To newObj.Description.ToCharArray.Length - 1
Debug.Print(Asc(newObj.Description.ToCharArray(i, 1)))
Next
End Sub
End Class
Take a look at XML deserialization 'standardising' line endings, how to stop it? (.NET). Does that soluton match what you're trying to do?