Reputation: 3351
I'm making a web project in .net for face authentication, when the face gets matched, both the images(captured and matched) are to be displayed in a div and along with that there should be confidence score to be populated.
Based on confident score, the authentications should be done.
Currently my problem is, the authentication is done fine, but the images are displayed blank and also the confidence score is displayed blank. I need to pop in the images and the confidence score into my webpage.
Below is my CSHTML
@section scripts
{
<script src="~/Scripts/blockUI.js"></script>
<script src="@Url.Content("~/Scripts/jquery.webcam.js")">
</script>
<script>
function MatchFindFunction() {
$.ajax({
type: "POST",
url: "/Image/FindSimilarImages", //Call the function FindSimilarImages present in the ImageController
contentType: "application/text; charset=utf-8",
dataType: "text",
success: function (data) {
if (data == "MATCHFOUND") {
$('#imageDisplay').append('<table border="1" cellspacing="1" cellpadding="4"><tr><th>Captured Image</th><th>Similar Image</th></tr><tr><td><img id="showsec" style="width:150px;height:150px;margin-top:5px;" src="@Session["CapturedImageData"]" /></td><td><img id="show" style="width:150px;height:150px;margin-top:5px;" src="@Session["ImageData"]" /></td></tr></table><table border="1" cellspacing="0" cellpadding="4" id="tblConfidence"><tr><td><label style="color:green;" id="Confidence">Confidence Score:@Session["ConfidenceScore"]</label></td></tr></table>');
setTimeout(function () {
setTimeout(function () {
$.blockUI({ message: '<h6> You are registered with, Welcome back. You will see the chatbot screen shortly. </h6>' });
window.location.href = '@Url.Action("ChatBot", "Home")';
},
7000);
}, 5000);
}
else if (data == "NOMATCHFOUND") {
$.blockUI({ message: '<h6> You are yet to register yourself with us, can you please proceed with register? </h6>' });
setTimeout(function () {
window.location.href = '@Url.Action("Register", "Home")';
}, 7000);
}
else {
//$('#ErrorMessage').show();
//$("body").scrollTop(0);
$.blockUI({ message: '<h6> You are yet to register yourself with us, can you please proceed with register? </h6>' });
setTimeout(function () {
window.location.href = '@Url.Action("Register", "Home")';
}, 7000);
}
}
});
}
</script>
<script>
$("#DivCamera").webcam({ //Display the camera in DivCamera division
width: 450,
height: 350,
mode: "save",
swffile: "@Url.Content("~/Scripts/jscam.swf")",
onTick: function () { },
onSave: function () {
},
onCapture: function () {
webcam.save("@Url.Content("~/Image/ImageCapture")/");
MatchFindFunction();
},
debug: function () { },
onLoad: function () { }
});
</script>
}
<div>
<label style="display:none;margin-left:500px; color:red;" id="ErrorMessage">Face API Subscription key Expired</label>
</div>
<div style="width:330px;height:420px; margin-top:20px;border: 4px solid #ccc; padding: 5px;float:left; margin-right:10px;">
</div>
<div id="DivCameraCapture" style="width:300px;margin-top:20px;margin-left:0px;float:left;margin-right:10px;">
<table style="border: 4px solid #ccc; padding: 5px; ">
<tr>
<td>
<label for="Livecamera" style="font-size:15px;color:black;margin-left:165px;" id="LblLivCamera">Live Camera</label>
</td>
</tr>
<tr>
<td>
<div id="DivCamera"></div>
</td>
</tr>
<tr>
<td>
<input type="submit" value="Login" class="btn-block" style="margin-left:90px;" onclick="webcam.capture();" />
</td>
</tr>
</table>
</div>
<div id="imageDisplay" style="width:330px;height:420px;margin-top:20px;border: 4px solid #ccc; padding: 5px;float:right;">
</div>
and my ImageController.cs(responsible to set the session values) is as below.
using System.IO;
using System;
using System.Collections.Generic;
using System.Web.Mvc;
using System.Threading.Tasks;
using Microsoft.ProjectOxford.Face;
using System.Net.Http;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Diagnostics;
using System.Web;
using System.Collections.Specialized;
using System.Runtime.CompilerServices;
using System.Linq;
//using Microsoft.ProjectOxford.Face.Contract;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections;
using System.Web.UI.WebControls;
using System.Text;
using System.Web.UI;
using System.Runtime.InteropServices;
using System.Security;
using System.Security.AccessControl;
using System.Threading;
using System.Configuration;
using System.Configuration.Provider;
using ComplianceBot.Models;
namespace ComplianceBot.Controllers
{
public class ImageController : Controller
{
CommonModels CommonModel = new CommonModels();
UserModels Usermodel = new UserModels();
public ActionResult Index()
{
return View();
}
public void ImageCapture() //Capturing the image and save as test.jpg
{
CommonModel.stream = Request.InputStream;
using (CommonModel.reader = new StreamReader(CommonModel.stream))
CommonModel.dump = CommonModel.reader.ReadToEnd();
CommonModel.path = Server.MapPath("~/test.jpg");
System.IO.File.WriteAllBytes(CommonModel.path, ConvertStringToByte(CommonModel.dump));
//Session["testURL"] = CommonModel.path;
}
private byte[] ConvertStringToByte(string strInput) //To convert the captured image to byte array
{
CommonModel.numBytes = (strInput.Length) / 2;
CommonModel.bytes = new byte[CommonModel.numBytes];
for (CommonModel.count = 0; CommonModel.count < CommonModel.numBytes; ++CommonModel.count)
{
CommonModel.bytes[CommonModel.count] = Convert.ToByte(strInput.Substring(CommonModel.count * 2, 2), 16);
}
return CommonModel.bytes;
}
public async Task<string> FindSimilarImages() //Compare the captured image with already strored images in the Image folder
{
CommonModel.MatchedImgcount = 0;
CommonModel.CapturedImgName = Server.MapPath("~/test.jpg");
byte[] capturedImageByteData = System.IO.File.ReadAllBytes(CommonModel.CapturedImgName);
string capturedImageBase64Data = Convert.ToBase64String(capturedImageByteData);
string capturedImageDataURL = string.Format("data:image/png;base64,{0}", capturedImageBase64Data);
Session["CapturedImageData"] = capturedImageDataURL;
CommonModel.DirInfo = new DirectoryInfo(Server.MapPath("~/Image/"));
if (!Directory.Exists(Server.MapPath("~/Image")))
{
Directory.CreateDirectory(Server.MapPath("~/Image"));
}
CommonModel.faceListName = Guid.NewGuid().ToString(); // Generating a Unique-ID
var faceServiceClients = new FaceServiceClient(CommonModel.FaceAPI_subscriptionKeyValue); //calling the Face API by passing subscription key
try
{
await faceServiceClients.CreateFaceListAsync(CommonModel.faceListName, CommonModel.faceListName, "face_Images"); //Calling the API service'CreateFaceListAsync' to create a facelist with Unique-ID.
}
catch (FaceAPIException ex) //If Subscription Key Expired
{
CommonModel.Errormesg = ex.ErrorMessage;
CommonModel.ErrorCode = CommonModel.ERRCODE_LIMITEXPIRED;
return CommonModel.ErrorCode;
}
CommonModel.DirInfo = new DirectoryInfo(Server.MapPath("~/Image/"));
Dictionary<string, string> DictionaryListofPersistanceIDAndImagePath = new Dictionary<string, string>();
try
{
foreach (var file in CommonModel.DirInfo.GetFiles("*.jpg"))
{
string imgPath = Server.MapPath("~/Image/") + file.ToString();
CommonModel.fStream = new FileStream(imgPath, FileMode.Open, FileAccess.Read);
var faces = await faceServiceClients.AddFaceToFaceListAsync(CommonModel.faceListName, CommonModel.fStream); //Adding of each jpg image content to the created facelist in the Face API using the service 'AddFaceToFaceListAsync'
DictionaryListofPersistanceIDAndImagePath.Add(faces.PersistedFaceId.ToString(), imgPath);//Storing the PersistedFaceId of the image returned by the Face API service and image path in dictionary
}
}
catch (FaceAPIException ex) //If morethan one face found while capturing the image
{
CommonModel.Errormesg = ex.ErrorMessage;
CommonModel.ErrorCode = CommonModel.ERRCODE_MORETHANONEFACEFOUND;
return ex.ErrorMessage;
}
CommonModel.CapturedImgName = Server.MapPath("~/test.jpg");
using (CommonModel.fileStream = System.IO.File.OpenRead(CommonModel.CapturedImgName))
{
var faceServiceClient = new FaceServiceClient(CommonModel.FaceAPI_subscriptionKeyValue);
var faces = await faceServiceClient.DetectAsync(CommonModel.fileStream); //Calling the Face API 'DetectAsync' to detect the captured image by sending the content of the captured image
foreach (var f in faces) //Loop through the returned faceid of the image
{
CommonModel.faceId = f.FaceId;
try
{
var result = await faceServiceClient.FindSimilarAsync(CommonModel.faceId, CommonModel.faceListName, CommonModel.requestCandidatesCount); // Matching the captured image with images by sending faceId and faceListName to the Face API 'FindSimilarAsync'
//The variable result contains the matched image's PersistedFaceId
CommonModel.MatchedImgpath = new string[CommonModel.requestCandidatesCount]; //Declare an array with size 'requestCandidatesCount' to store the matched images path
foreach (var fr in result) //Loop through the PersistedFaceId of matched faces
{
if (fr.Confidence >= 0.8) //To check whether the confidence value of the matched image is >=0.8
{
Session["ConfidenceScore"] = fr.Confidence;
if (DictionaryListofPersistanceIDAndImagePath.ContainsKey(fr.PersistedFaceId.ToString()))//To check whether the Persistance id is present in the dictionary
//if present retrive the curresponding image-path of that PersistedFaceId.
{
CommonModel.MatchedImgpath[CommonModel.MatchedImgcount] = DictionaryListofPersistanceIDAndImagePath[fr.PersistedFaceId.ToString()]; //Store the image-path in an array.This array contains all the matched image path which have confidence-value >=0.8
CommonModel.MatchedImgcount = CommonModel.MatchedImgcount + 1;
CommonModel.path = DictionaryListofPersistanceIDAndImagePath[fr.PersistedFaceId.ToString()];
byte[] imageByteData = System.IO.File.ReadAllBytes(CommonModel.path);
string imageBase64Data = Convert.ToBase64String(imageByteData);
string imageDataURL = string.Format("data:image/png;base64,{0}", imageBase64Data);
Session["ImageData"] = imageDataURL;
Usermodel.LoggedUsername = CommonModel.path.Substring(CommonModel.path.LastIndexOf("\\"), CommonModel.path.Length - CommonModel.path.LastIndexOf("\\")); //retrive username from the matched imagename
Usermodel.LoggedUsername = Usermodel.LoggedUsername.Remove(0, 1);
Usermodel.LoggedUsername = Path.GetFileNameWithoutExtension(Usermodel.LoggedUsername);
Session["loggedUserName"] = Usermodel.LoggedUsername.ToString();
}
}
}
}
catch (FaceAPIException ex)
{
CommonModel.Errormesg = ex.ErrorMessage;//If Image Folder contains zero images
CommonModel.ErrorCode = CommonModel.EMPTYIMAGEFOLDER;
return ex.ErrorMessage;
}
}
}
if (CommonModel.MatchedImgcount != 0)
{
return CommonModel.MATCHFOUND;
}
else
{
return CommonModel.NOMATCHFOUND;
}
}
}
}
please let me know where am I going wrong getting the session data, I mean, the images and scores. Again, the authentication is working fine, I just need to get these details.
Thanks
Upvotes: 0
Views: 62
Reputation: 24247
The AJAX call to FindSimilarImages
will set the Session variables on the server side, but that has no effect on the client-side AJAX success
function where you are trying to use those values. The success
function is rendered to the browser only once, before the FindSimilarImages
call happens, and so the Session values used during rendering is what will be used until the page is reloaded.
The solution would be to have FindSimilarImages
return a JSON datastructure that not only contains "MATCHFOUND" but also the URL of the image and the Score, and then use both from the data
object inside the success
function.
Upvotes: 1