First time i got impressed with an CIO is the way he bring SAAS based solutions each and every business unit and it turned out to be quick solutions so AI could be next tactical or visionary thing. so interesting to review those ideas lot of good examples where Netflix done microservices and could streams Gigs of data.lot of good examples..around
Responsive design is a frequently desired feature for web applications. As developers, we have to support a variety of devices and screen sizes. CSS is a great tool for simple use-cases and very efficient performance-wise. However, managing complex media queries may become burdensome even with the use of preprocessors (SASS, PostCSS, LESS, etc.).
Thanks to the MatchMedia API, Vue.js can greatly reduce the complexity of handling media queries and responsive design. It provides seamless integration with a component-based architecture, keeping a clean declarative and semantic approach.
In this article, you will explore features available to the vue-mq plugin for media queries.
Prerequisites
If you would like to follow along with this article, you will need:
Warning: This plugin relies on the matchMedia API to detect screen size changes. So, for older browsers and Internet Explorer, you should utilize Paul Irish’s matchMedia polyfill
This tutorial was verified with Node v15.8.0, npm v7.5.4, Vue v12.6.11, and vue-mq v1.0.1.
Using vue-mq
First, to use vue-mq, open your terminal and navigate to your existing Vue project directory. Then, run the following command:
npminstall vue-mq@1.0.1
Next, with your code editor, edit your Vue project and import the library:
importVueMqfrom'vue-mq'
Define your custom breakpoints when registering the plugin. Keys are breakpoints and values are in pixels:
In this example, four breakpoints are defined. A mobile, tablet, laptop, and desktop screen size.
Using vue-mq with Conditional Rendering
Very often when dealing with responsive design you will want to render elements conditionally.
For instance, display a specific menu for mobile devices only.
In order to accomplish that functionality, you can use the reactive $mq property which is accessible inside each instance of a component. Its value will always be the current breakpoint.
This component will render when the current screen size satisfies the conditional. If you defined the breakpoint for “mobile” to be 450 pixels, this component will render for screen sizes up to 450px.
vue-mq also provides a shorthand for this syntax with a global mq-layout component that acts as a conditional slot:
Notice the plus sign (+) after the “tablet” breakpoint name. This instructs vue-mq to target the breakpoint and all the larger breakpoints as well.
Using vue-mq with Prop Values
Another very common use-case is the computation of different values based on screen size.
For example, let’s say you want to display a responsive grid of items:
on mobile you want 2 columns
on tablets you want 3 columns
on laptops you want 4 columns
In other words, you just have to pass down a prop with different values according to screen size to the exact same grid component. It will have the responsibility to display the right number of columns.
vue-mq provides a global filter for mapping breakpoints to values, using declarative rules:
Keep in mind that this plugin is enforcing a mobile-first approach. Values will default to the closest smaller breakpoints value if not defined explicitly.
If you omitted the “tablet” rule (tablet: 3), it will fall back to the “phone” rule for “tablet” screen sizes and display 2 columns.
In the same way, if you need values that are more complex, move it in a computed prop:
<template><responsive-title>{{ displayText }}</responsive-title></template><script>exportdefault{
computed:{displayText(){returnthis.$mq==='mobile'?'You are on a mobile device':'You are on a larger device'}}}</script>
This code will display "You are on mobile device" or "You are on a larger device" depending on your screen size.
Using vue-mq with Responsive Classes
Sometimes, you also want to change style quickly via CSS. The trick is to use a breakpoint name as a computed class on the element you want to style.
Microsoft Cognitive Services, or as I like to call it, AI for the common folk, allows your applications to hear, see, and understand just like you would. Think of all the people you know, your best friends, your family, your boss, people you dislike; are you thinking of their faces?
When your boss knocks on your cubicle with a coffee cup in his hand, and says, “Hey Peter,” you instantly know if you'll need to work the weekend. You see his emotions in his face.
Advertisement
Microsoft Cognitive Services puts all that power into your applications. And it's easy! If you can call a REST API, your application can do amazing things. Although the focus of this article is on a very narrow capability, recognizing faces, let me tell you some other amazing capabilities Cognitive Services has.
Microsoft Cognitive Services: The Vision API
Microsoft Cognitive Services is comprised of Vision, Speech, Knowledge, Search, and Language APIs. Within each of these buckets, there are numerous capabilities.
The Vision API allows you to distill actionable information from images. This means that you show it a picture, and it tells you what it sees in the picture: it describes it back to you. Yes really. You show it a picture of a dog, and it'll tell you “Hey, this is a dog.” But it gets better. It can also tell you if the picture's black and white, or what the various important colors are in it. It can do handwriting or OCR recognition. It can differentiate among line art, clip art, or photographs. It can flag adult or racy content, generate thumbnails, detect faces, even identify emotions on the faces. It can even see an image and recognize celebrities or landmarks, or you can create your own models, say dog breeds, and it recognizes what breed a dog is, by showing it a picture of a dog! Any dog!
In this article, I'll show the Vision API a picture of a person, and it will recognize who the person is. Specifically, the Face API part of the Vision API will do this.
The speech and language APIs are somewhat interconnected. They can do things like speech to text and text to speech. They can even do things like recognize a language if you provide some input text. Or detect sentiment, key phrases, and break apart sentences if you provide some input text. It can even do translations between languages. Pair these together and you can do real-time text-to-speech in one language, translate to another, and text-to-speech in another language. These are things you can build, easily, if you can call a REST API. Oh, did I mention that it can also do spell check? I know you're laughing - haven't we had spell check for ages in Microsoft Word? Yes, but powered by the cloud, it's far more sophisticated.
Perhaps the most interesting part of the speech and language APIs is LUIS, or Language Understanding Intelligent Service. It allows your applications to understand natural language as input and derive actionable information out of them. For instance, wash my car, or clean my car, are about the same thing, aren't they? You can pair this with, say, the bot framework, and speech-to-text, and you now have a completely new level of application, specific to your domain. Imagine building the next Alexa/Cortana/Siri for your business applications. Would you like to walk into a meeting room and ask, “Is this meeting room free?”
Building these kinds of systems is easy! And you can write it in any platform you wish. You could build it in Node.js and run it on a $39 Arduino.
There's so much that you can build easily with Cognitive Services. I hope to talk about many such capabilities in upcoming articles, but for now, let me return to the focus of this article, identifying faces.
Identifying vs. Recognizing
Let's start by defining the problem domain. Cognitive Services allow you to easily recognize faces in a picture. You show it a picture, and it tells you that at certain rectangle position, there is a face. It'll even tell you things like this person is a female, age 27, who is 99% happy, 1% angry, 0.9% surprised, with a head tilted in a certain way, is bald or not, wears eyeglasses, and a lot more!
As impressive as that is, that's easy! In this article, I'll go the next step: I'll first build a library of people with associated faces. For instance, I'll show former president Obama, with pictures of him. And there's another person, and yet another person, and hey look, yet another person. You could have literally thousands of faces in a library, but I'll keep it demo level at three people. Then I'll input a picture that the program has never seen before. This picture is of a person, a person who is in our library. Or it could be a picture with more than one person, or a picture where one of the people in the picture is part of our library. And the computer will “identify” the person, as in “I think this is Barack Obama, and my confidence is 99%.”
Before we get rolling, let's understand some basic theory first.
How Identification Works
In order to perform identification, you first need to create a Person group. This is your dataset of people among which recognition will be performed.
Within that Person Group, you add numerous images of people. The number of Persons has a subscription-level limit and a Person Group level limit. Free tier subscriptions have a limit of 1,000 persons per Person Group and 1,000 persons total per subscription. The S0-level tier subscriptions have these limits: 10,000 Persons per Person Group, 100M Persons total and 1M Person Groups per subscription. My demo will have three persons, so I think I can get by with the free tier. But think about it; 100 million persons. Imagine the power this puts in your hands.
Once you have created the Persons Group and the list of Persons, the next thing you do is add faces to each person. This is simply a matter of uploading pictures of each Person with a clear view of their faces. The pictures need to meet the following criteria:
Each person has a maximum of 248 faces - that's 248 versions of the same person.
The image format must be JPEG, PNG, GIF (the first frame), or BMP.
The image file size should be larger than or equal to 1KB but no larger than 4MB.
The detectable face size is between 36x36 to 4096x4096 pixels. The faces out of this range will not be detected.
You can submit a picture with many faces, but you must specify the rectangle where the specific person of interest is. The rectangle specified by targetFace should contain exactly one face. Zero or multiple faces will be regarded as an error.
Out of detectable range face size, large head-pose, or very large occlusions also result in fail to add a person's face.
Easy enough! I think I can find plenty of pictures of the former president.
Once you are finished managing persons and person faces, you train the model. Although this sounds about as bad as going to the gym, in this case, it's a REST call.
Finally, you submit an input image and the AI Gods tell us who this person is! Doesn't that sound easy? Let's get started!
I must mention that given the number of steps, it's not possible for me to show every line of code in this article. However, you can download and set up the finished code. The instructions can be found in the “set up the code” section of this article.
Set Up the Face API in Azure
Like many Cognitive Services' APIs, in order to use the Face API, you need to provision it for use in the Azure Portal. Go ahead and log in to the Azure portal, click on the “Create a resource” link, and choose to create a new instance of the Face API, as shown in Figure 1.
Among other things, you'll need to specify a pricing tier. For the purposes of this article, the F0 subscription-level free tier is fine.
Once you've created this resource, grab the endpoint address and the two keys. I chose to put mine into a file called config.ts, as can be seen in Listing 1.
Calls to the Face API are simple REST calls. They can be GET/POST/DELETE or any other such common HTTP verb. But the calls must be authenticated. To authenticate the call, you need to pass in a specific HTTP header called Ocp-Apim-Subscription-Key, and then pass in either of the two keys from Listing 1. You might wonder, why two keys? Well, the two keys are equivalent. You can pass either. The reason they provide two is for redundancy. If one key gets compromised, you can choose to use the other while the first one is regenerated.
I'm using a node package called request to make REST API calls. The code to provide the authentication header along with a default content type can be seen in Listing 2.
Before I dive into the depths of identifying faces, let's first understand the capabilities of the Face API. As the name suggests, the Face API lets you work with faces, human faces. The focus of this article is recognizing people, but the Face API can do so much more.
Finding Similar Faces
As the name suggests, the Face API can accept an image with a face, or an image with multiple faces, and a single face specified as coordinates, and then given a set of faces, it returns a set of faces that looks the most similar to the target face.
Grouping Faces
Given a set of input faces, the Face API groups them into several groups based on similarity.
Detection
Detection, as the name suggests, detects human faces in an image. But it can do so much more. When you call the Detect method, you have a choice of requesting multiple details of the recognized faces. The more details you request, the longer the request takes. In your inputs to the detect method, you can pass in various optional request parameters.
returnFaceID: This is a unique face IDof the detected face created by the detection API. This expires 24hours after a detection call; you'll see later in this article how this is useful against recognizing faces in multiple sets of Person Groups.
returnFaceLandmarks: Face landmarks are a series of detailed points on a face, typically points of face components like the pupils, canthus, or nose. Bydefault, there are 27 predefined landmark points that provide all of the details of a recognized face, including eyebrows, and all relevant positions to the nose, lips, and eyes.
returnFaceAttributes: This is a comma-separated list of various attributes of the face you'd like to have returned. Supported face attributes include age, gender, headPose, smile, facialHair, glasses, emotion, hair, makeup, occlusion, accessories, blur, exposure, and noise. Yes, you can pass in an image, and the Face API will tell you if the person looks angry or not using the "emotion" attribute. You could write an interesting analysis program to prove that perhaps bald people are usually less angry than hairier people by using the "hair,emotion" face attributes.
Let's see a simple example of attribute detection in a passed-in image. As you can imagine, the call to the Face API is a simple REST call, as shown here:
The URI is quite straightforward. The magic is in the requestOptions variable.
I start by creating the basic request options with the authentication header and using the method shown in Listing 2, as follows:
const requestOptions = getRequestOptions();
Next, I craft up the params querystring. It's in this params variable that I specify what I'd like to have detected. I'll just specify everything; I want landmarks and I want all the attributes.
The input image I am using can be seen a little further on, in Figure 5.
Running this code sends back a huge JSON object; after all, we did ask it to analyze quite a bit. At a high level, the JSON object is an array of objects. Why an array? Because there could be multiple faces in the same image. You can analyze up to 64 faces in one call and each face needs to be between 36x36 to 4096x4096 wide.
Advertisement
In each of the objects in the array, you'll find four properties:
faceID: a unique GUID that helps the Face API remember the given face for up to24hours
faceRectangle : wherein the picture the face appears
faceLandmarks : the various landmarks detected on the face
faceAttributes : an object representing the various attributes analyzed
Of the four, faceID and rectangle are quite straightforward, so let me dive a bit into the landmarks and attributes.
Landmarks
Under landmarks, you'll see numerous properties, each with an x,y coordinate. The following properties are returned:
As you can see, pretty much the whole face is broken down into landmarks; you can easily zero in on the entire face structure given these values. But wait, there's more, in attributes.
Attributes
Under attributes, you request all the attributes that the Face API detect method supports, and as you can imagine, you get a lot of information back. I encourage you to try this out for yourself, but meanwhile, let me show you some interesting returned properties.
Attributes lets you know if the person is smiling, and by how much:
"smile": 0.27,
It lets you know exactly how their head is positioned:
I can see many uses for this. Imagine that when you unlock your significant other from the car trunk, it would be quite handy to have the emotion API help you out when you need it the most. (Just kidding!)
It also tells you the quality of the picture as blur, exposure, and noise:
It tells you if the person is wearing any make up:
"makeup":{"eyeMakeup":false,"lipMakeup":false},
I, for one am thrilled that our ex-president looks good without make up on, or for that matter without any accessories, which means that there's just an empty array. Accessories include things like earrings, tattoos, and other ornaments.
"accessories": [],
If you're having a hard time recognizing the person via code, you can programmatically find out if the face is occluded:
And finally, Cognitive Services provides you with an analysis of their hair. It returns a JSON object telling you on a scale of 0-1 how bald the person is. The former president is 0.05 bald, if you're interested. And it does an analysis on their hair color as an array of color and confidence, so Obama's hair is gray, with a confidence of 1.0, black with confidence of 0.28, etc.
A Practical Example
The real power of cognitive API is unlocked when you start combining many APIs. Imagine a natural language interactive robot. The kind you speak to and it responds back in a voice. It could look at your face and recognize who you are when you walk into a store. It could recognize your emotion in the way you look or speak. It can understand thousands of languages. And it can understand natural language with the help of LUIS. When it analyzes your face, it can know exactly what emotion you're exhibiting. If you look angry, it knows, and reacts accordingly. If you're happy, it perhaps tries to sell you more stuff.
With Cognitive Services, today, you can build a robot that will:
Recognize you soon as you walk into the store
Speak your language
Talk to you in a natural language
Tailor its help to exactly how you feel at the moment
Given how easy all of this is, I'm surprised we don't already have it. I'm sure that we will have all of it before the first commercial flying car.
For now, let's get back to the first part of this problem, which is recognizing you soon as you walk into the store.
Creating a Person Group
Creating a Person Group is a matter of issuing a PUT request to a URL that looks like this:
The personGroupId is simply a user-provided string. The valid characters include numbers, English letters in lower case, a hyphen ("-") and an underscore ("_"). The maximum length of the personGroupId is 64. Along with such a request, you need to include a request body with the following JSON object:
{'name': personGroupId}
The full code for creating the Person Group can be seen in Listing 3.
Note that the request URL includes the personGroupId. This is how you tell the Face API which Person Group a Person belongs in. Also, you need to specify the name of the Person you're adding as a JSON object that looks like this:
{'name': personName}
The name is the display name of the target person. This can be up to 128 characters. You can also optionally send some user-provided data attached to the Person as a userData property on the input JSON object. You can find the full listing for the createPerson method in Listing 4.
As you can see from the URL, you're posting to the /persistedFaces URL for the given person in the given person group. The next question is: How do you specify the actual file contents? There are two ways.
Either you can specify the content-type header to be application/json, and send the following JSON object in the body of the POST request:
{url:'url_to_the_image'}
Or you can specify the content-type header to be application/octet-stream and send the contents of the image. The method to read the contents of the image can be seen in Listing 5.
Listing 5: Read contents of the image
exportfunctionreadImage(filePath: string) {
const fileData = fs.readFileSync(filePath).toString("hex");
const result = [];
for (let i = 0; i < fileData.length; i += 2) {
result.push(parseInt(fileData[i] + "" + fileData[i + 1], 16))
}
returnnew Buffer(result);
}
The code to issue a POST request is quite similar to Listing 3 and Listing 4, so I'll omit that here. You can find the full code for this article in the “Set up the code” section of this article**.**
Train the Model
Once you've created the Person Group, added Persons, and added Faces to the Persons, you need to train the model before you can start asking it to identify people. Training the Person Group is yet another REST call. You simply issue a POST request to the following URL:
The important difference here is that the train operation is a long-running operation. You don't immediately get a success or failure response. Instead, you need to call a specific URL to check the status of the training. The URL is here:
This request may take a long time to complete, so usually you call this endpoint every few seconds and check the return JSON object. The return JSON object has the following properties:
Status: With values notstarted, running, succeeded, or failed
createdDateTime : A UTC time informing you ofwhen the Person Group was created
lastActionDateTIme : A UTC time informing you of the last timethis Person Group was modified. This can be `null` if you've never trained the group.
Message: If the training fails for any reason, you'll find the reason for the failure here. For success, this will be blank.
All there is left to do now is to call the /training URL in a loop, and when the status succeeds, ensure that you stop calling the loop. This is essential because you are under a rate limit, and you're paying for the calls you make. You don't want to call too often, and you don't want to call unnecessarily. The code for training the Person Group can be seen in Listing 6.
Finally, I added Donald J. Trump as the third person to round up our stellar group of individuals. The specific pictures I added can be seen in Figure 4.
When I added the current president into the person group, I got the following GUID as my identifier:
Now that I've registered three persons with their faces, let's supply a sample image and run the identification logic.
Identify and Recognize the Person
The way recognition works is that first you have to identify the Person. If the last sentence didn't make any sense, here's what I mean. First you have to send the picture to the Face API and have the Face API detect a face in the picture. In doing so, the Face API returns a GUID of the face. This GUID is temporary in nature; it's only good for 48 hours. Remember, the Person IDs are permanent. The code to detect the face and return a Face ID can be seen in Listing 7.
Note that in the body, you specify the number of candidates you'd like to have in the result set, and the minimum confidence threshold the recognition should meet. Also, you pass in the Face ID that you got from Listing 7.
At this point, all you have to do now is to make the request to get the Face ID, and then another request to identify the Person. The code can be seen in Listing 8.
If you match GUID 66ec4630-5369-4830-a20b-0f329d6eaf56 with the Person IDs above, you'll see that it's President Obama. I realize that he is a very famous person and our dataset was only three people, but this can scale to 100 million people.
Set Up the Code
This article had a lot of steps, and I wasn't able to show every single method in this article. However, you can get the full source code and set it up on your computer easily. Just follow the following steps:
Now, with the project open in Visual Studio Code, examine the index.ts.
Advertisement
You'll find code there, commented out as step #1, step #2, and step #3. To perform the steps of creating a Person Group, train the Person Group, and detect and identify a Person. Finally, do step #4 to delete the Person Group when you are done.
You can uncomment the relevant portions, hit F5 to perform the necessary steps one by one, and then check the debug log.
Conclusion
What's the value of being able to send in a picture, and have the computer recognize who it is in a matter of seconds, across 100 million people?
Imagine a stadium, where at the entrance people read a sign. And by that sign is a small camera, comparing every person with possible terrorists?
Or, what if you walk into a store, and a camera there instantly recognizes you and sends you discount codes on your phone that you must use in the next 20 minutes at that store.
Or perhaps something more mundane: You walk into the room, the computer recognizes you, and automatically sets the lights and music per your preference.
The possibilities are endless, and this is just a single capability of the Microsoft Cognitive Services. I hope to talk about those among other things, in future articles.