Reputation: 1719
I am trying to use Microsoft Cognitive Face API for the first time. Documentation gives quite a simple method to detect face from memory stream. I am trying to detect faces from images located inside a folder. Right now there is only one image inside the folder. The issue is whenever the control reaches the following line:
var faces = await faceServiceClient.DetectAsync(memStream, true, true);
it terminates without any exception or error. Here is the complete code I have written.
using Microsoft.ProjectOxford.Face;
using Microsoft.ProjectOxford.Common;
using Microsoft.ProjectOxford.Face.Contract;
using System;
using System.Collections.Generic;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
namespace FaceDetection.FaceDetect
{
class Program
{
static void Main(string[] args)
{
Console.Title = "Face Detect";
Start();
}
static async Task Stop()
{
await Close();
}
private static Task Close()
{
return Task.Run(() =>
{
Environment.Exit(0);
});
}
static async Task ReStart(string _reason = "")
{
Console.WriteLine(_reason + "To restart the process press 'R'. To exit press 'X'");
var _response = Console.ReadLine();
if (_response == "r" || _response == "R")
await Start();
else
await Stop();
}
static async Task Start()
{
Console.Clear();
Console.WriteLine("Enter Folder Path");
string imageFolderPath = Console.ReadLine();
if (!Directory.Exists(imageFolderPath))
{
await ReStart("Folder does not exist! ");
}
else
{
await SaveFiles(imageFolderPath);
}
}
static async Task SaveFiles(string imageFolderPath)
{
try
{
DirectoryInfo dInfo = new DirectoryInfo(imageFolderPath);
string[] extensions = new[] { ".jpg", ".jpeg" };
FileInfo[] files = dInfo.GetFiles()
.Where(f => extensions.Contains(f.Extension.ToLower()))
.ToArray();
if (files.Length == 0)
await ReStart("No files found in the specified folder! ");
else
{
string subscriptionKey = "ADSFASDFASDFASDFASDFASDFASDF";
if (!String.IsNullOrEmpty(ConfigurationManager.AppSettings["subscriptionKey"]))
subscriptionKey = ConfigurationManager.AppSettings["subscriptionKey"].ToString();
//var stringFaceAttributeType = new List<FaceAttributeType> { FaceAttributeType.Smile, FaceAttributeType.Glasses, FaceAttributeType.Gender, FaceAttributeType.Age };
//IEnumerable<FaceAttributeType> returnFaceAttributes = stringFaceAttributeType;
IFaceServiceClient faceServiceClient = new FaceServiceClient(subscriptionKey);
foreach (FileInfo file in files)
{
try
{
using (FileStream fileStream = File.OpenRead(imageFolderPath + "\\" + file.Name))
{
MemoryStream memStream = new MemoryStream();
memStream.SetLength(fileStream.Length);
fileStream.Read(memStream.GetBuffer(), 0, (int)fileStream.Length);
//Used following commented code to make sure MemoryStream is not corrupted.
//FileStream _file = new FileStream(imageFolderPath + "\\test.jpg", FileMode.Create, FileAccess.Write);
//memStream.WriteTo(_file);
//_file.Close();
//memStream.Close();
try
{
//This line never returns a result. The execution terminates without any exception/error.
var faces = await faceServiceClient.DetectAsync(memStream, true, true);
if (faces != null)
{
foreach (var face in faces)
{
var rect = face.FaceRectangle;
var landmarks = face.FaceLandmarks;
}
}
else
Console.WriteLine("No face found in image: " + file.FullName);
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
}
catch (Exception ex)
{
Console.WriteLine("There was an error!");
}
}
}
}
catch (Exception ex)
{
Console.WriteLine("There was an error!");
}
await ReStart();
}
}
}
Can someone point out what am I missing. Why is this code not working?
Upvotes: 0
Views: 396
Reputation: 2973
When you read the file in to the MemoryStream, your read pointer is advanced to the end. So memStream
passed in to DetectAsync()
appears empty. The fact is you need not copy your file to memory. You could simply pass in the FileStream
after opening.
using (FileStream fileStream = File.OpenRead(imageFolderPath + "\\" + file.Name))
{
try
{
var faces = await faceServiceClient.DetectAsync(fileStream, true, true);
if (faces != null)
{
foreach (var face in faces)
{
var rect = face.FaceRectangle;
var landmarks = face.FaceLandmarks;
}
}
else
{
Console.WriteLine("No face found in image: " + file.FullName);
}
catch (Exception ex)
{
Console.WriteLine("Error");
}
}
Alternatively, you can rewind the memory stream by setting memStream.Position = 0
before calling DetectAsync
.
Upvotes: 2