3. @slorello
“ “
The Goal of computer vision
is to write computer
programs that can interpret
images
Steve Seitz
4. @slorello
1. What is a Digital Image?
2. Hello OpenCV in .NET
3. Convolution and Edge Detection
4. Convolutional Neural Networks
5. Facial Detection
6. Facial Detection with Vonage Video API
Agenda
36. @slorello
var imageData = new ImageData()
{
ImagePath = filename
};
var predictor = _mlContext.Model.CreatePredictionEngine<ImageData,
ImagePrediction>(_model);
var prediction = predictor.Predict(imageData);
Detector.cs
37. @slorello
var imageData = new ImageData()
{
ImagePath = filename
};
var predictor = _mlContext.Model.CreatePredictionEngine<ImageData,
ImagePrediction>(_model);
var prediction = predictor.Predict(imageData);
Detector.cs
38. @slorello
var appId = _config["APP_ID"];
var privateKey = _config["privateKeyPath"];
var creds = Credentials.FromAppIdAndPrivateKeyPath(appId, privateKey);
var content = new { type = "text", dogPrediction };
var message = new { content };
var to = new { type = "whatsapp", number = toNum };
var from = new { type = "whatsapp", number = fromNum };
var request = new { to, from, message };
var uri = new Uri("https://api.nexmo.com/v0.1/messages");
var response = ApiRequest.DoRequestWithJsonContent<JObject>
("POST", uri, request, ApiRequest.AuthType.Bearer, creds);
WhatsAppController.cs
39. @slorello
var appId = _config["APP_ID"];
var privateKey = _config["privateKeyPath"];
var creds = Credentials.FromAppIdAndPrivateKeyPath(appId, privateKey);
var content = new { type = "text", dogPrediction };
var message = new { content };
var to = new { type = "whatsapp", number = toNum };
var from = new { type = "whatsapp", number = fromNum };
var request = new { to, from, message };
var uri = new Uri("https://api.nexmo.com/v0.1/messages");
var response = ApiRequest.DoRequestWithJsonContent<JObject>
("POST", uri, request, ApiRequest.AuthType.Bearer, creds);
WhatsAppController.cs
40. @slorello
var appId = _config["APP_ID"];
var privateKey = _config["privateKeyPath"];
var creds = Credentials.FromAppIdAndPrivateKeyPath(appId, privateKey);
var content = new { type = "text", dogPrediction };
var message = new { content };
var to = new { type = "whatsapp", number = toNum };
var from = new { type = "whatsapp", number = fromNum };
var request = new { to, from, message };
var uri = new Uri("https://api.nexmo.com/v0.1/messages");
var response = ApiRequest.DoRequestWithJsonContent<JObject>
("POST", uri, request, ApiRequest.AuthType.Bearer, creds);
WhatsAppController.cs
41. @slorello
var appId = _config["APP_ID"];
var privateKey = _config["privateKeyPath"];
var creds = Credentials.FromAppIdAndPrivateKeyPath(appId, privateKey);
var content = new { type = "text", dogPrediction };
var message = new { content };
var to = new { type = "whatsapp", number = toNum };
var from = new { type = "whatsapp", number = fromNum };
var request = new { to, from, message };
var uri = new Uri("https://api.nexmo.com/v0.1/messages");
var response = ApiRequest.DoRequestWithJsonContent<JObject>
("POST", uri, request, ApiRequest.AuthType.Bearer, creds);
WhatsAppController.cs
43. @slorello
1. Use Haar-Like features as masks
2. Use integral images to calculate relative
shading per these masks
3. Use a Cascading Classifier to detect faces
Viola-Jones Technique
47. @slorello
● Construct Cascading Classifier
● Run Classification
● Use Rectangles from classification to draw
boxes around faces
48. @slorello https://github.com/slorello89/FacialDetection
var faceClassifier = new CascadeClassifier(Path.Join("resources",
"haarcascade_frontalface_default.xml"));
var img = CvInvoke.Imread(Path.Join("resources", "imageWithFace.jpg"));
var faces = faceClassifier.DetectMultiScale(img,
minSize: new System.Drawing.Size(300,300));
foreach(var face in faces)
{
CvInvoke.Rectangle(img, face,
new Emgu.CV.Structure.MCvScalar(255, 0, 0), 10);
}
51. @slorello
● Create a WPF app
● Add the OpenTok.Client SDK to it
● Add a new class implementing IVideoRender
called and extending Control
FaceDetectionVideoRenderer
● Add a Control to the Main Xaml file where we’ll
put publisher video - call it “PublisherVideo”
● Add a Detect Faces and Connect button
56. @slorello
● Intercept each frame before it’s rendered.
● Run face detection on each frame
● Draw a rectangle on each frame to show
where the face is
● Render the Frame
62. @slorello
● What’s a good Feature?
● Detect Features with Orb
● Feature Tracking with a BF
tracker
● Project an image.
63. @slorello
● A good feature is a part
of the image, where
there are multiple edges
● Thus we often think of
them as Corners
● We can use the ORB
method (Oriented FAST
and rotated BRIEF)
https://www.slideshare.net/slksaad/multiimage-matching-using-multiscale
-oriented-patches
64. @slorello https://github.com/slorello89/FeatureDetection
var orbDetector = new ORBDetector(10000);
var features1 = new VectorOfKeyPoint();
var descriptors1 = new Mat();
orbDetector.DetectAndCompute(img, null, features1, descriptors1, false);
Features2DToolbox.DrawKeypoints(img, features1, img, new Bgr(255, 0, 0));
66. @slorello
● Now that we have some features we can
match them to features in other images!
● We’ll use K-nearest-neighbors matching
on the Brute-force matcher
67. @slorello https://github.com/slorello89/FeatureDetection
var bfMatcher = new BFMatcher(DistanceType.L1);
bfMatcher.Add(descriptors1);
bfMatcher.KnnMatch(descriptors2, knnMatches, k:1,mask:null,compactResult:true);
foreach(var matchSet in knnMatches.ToArrayOfArray())
{
if(matchSet.Length>0 && matchSet[0].Distance < 400)
{
matchList.Add(matchSet[0]);
var featureModel = features1[matchSet[0].TrainIdx];
var featureTrain = features2[matchSet[0].QueryIdx];
srcPts.Add(featureModel.Point);
dstPts.Add(featureTrain.Point);
}
}
var matches = new VectorOfDMatch(matchList.ToArray());
var imgOut = new Mat();
Features2DToolbox.DrawMatches(img, features1, img2, features2, matches,
imgOut, new MCvScalar(255, 0, 0), new MCvScalar(0, 0, 255));
75. @slorello
A Little More About Me
● .NET Developer & Software Engineer
● .NET Developer Advocate @Vonage
● Computer Science Graduate Student
@GeorgiaTech - specializing in Computer
Perception
● Blog posts: https://dev.to/slorello or
https://www.nexmo.com/blog/author/stevelorello
● Twitter: @slorello
76. @slorello
A Little More About Vonage
● Vonage provides a full suite of communications APIs
○ https://developer.nexmo.com
○ Coupon Code: 21GCSLH €10
● Vonage Video API
○ https://www.vonage.com/communications-apis/video/
83. @slorello https://romannurik.github.io/SlidesCodeHighlighter/
var faceClassifier = new CascadeClassifier(Path.Join("resources",
"haarcascade_frontalface_default.xml"));
var img = CvInvoke.Imread(Path.Join("resources", "imageWithFace.jpg"));
var faces = faceClassifier.DetectMultiScale(img,
minSize: new System.Drawing.Size(300,300));
foreach(var face in faces)
{
CvInvoke.Rectangle(img, face,
new Emgu.CV.Structure.MCvScalar(255, 0, 0), 10);
}