// main.cpp
// Copyright (c) Microsoft Open Technologies, Inc.
// All rights reserved.
//
// (3 - clause BSD License)
//
// Redistribution and use in source and binary forms, with or without modification, are permitted provided that
// the following conditions are met:
//
// 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the
// following disclaimer.
// 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the
// following disclaimer in the documentation and/or other materials provided with the distribution.
// 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or
// promote products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
// WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
// PARTICULAR PURPOSE ARE DISCLAIMED.IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT(INCLUDING
// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
#include "pch.h"
#include <opencv2/core.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/objdetect.hpp>
#include <opencv2/features2d.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/videoio/cap_winrt.hpp>
// Switch definitions below to apply different filters
// TODO: add UX controls to manipulate filters at runtime
//#define COLOR
#define CANNY
//#define FACES
using namespace cv;
namespace video_capture_xaml {
// forward declaration
void cvFilterColor(Mat &frame);
void cvFilterCanny(Mat &frame);
void cvDetectFaces(Mat &frame);
CascadeClassifier face_cascade;
String face_cascade_name = "Assets/haarcascade_frontalface_alt.xml";
void cvMain()
{
//initializing frame counter used by face detection logic
long frameCounter = 0;
// loading classifier for face detection
face_cascade.load(face_cascade_name);
// open the default camera
VideoCapture cam;
cam.open(0);
Mat frame;
// process frames
while (1)
{
// get a new frame from camera - this is non-blocking per spec
cam >> frame;
frameCounter++;
// don't reprocess the same frame again
// if commented then flashing may occur
if (!cam.grab()) continue;
// image processing calculations here
// Mat frame is in RGB24 format (8UC3)
// select processing type
#if defined COLOR
cvFilterColor(frame);
#elif defined CANNY
cvFilterCanny(frame);
#elif defined FACES
// processing every other frame to reduce the load
if (frameCounter % 2 == 0) {
cvDetectFaces(frame);
}
#endif
// important step to get XAML image component updated
winrt_imshow();
}
}
// image processing example #1
// write color bar at row 100 for 200 rows
void cvFilterColor(Mat &frame)
{
auto ar = frame.ptr(100);
int bytesPerPixel = 3;
int adjust = (int)(((float)30 / 100.0f) * 255.0);
for (int i = 0; i < 640 * 100 * bytesPerPixel;)
{
ar[i++] = adjust; // R
i++; // G
ar[i++] = 255 - adjust; // B
}
}
// image processing example #2
// apply edge detection aka 'canny' filter
void cvFilterCanny(Mat &frame)
{
Mat edges;
cvtColor(frame, edges, COLOR_RGB2GRAY);
GaussianBlur(edges, edges, Size(7, 7), 1.5, 1.5);
Canny(edges, edges, 0, 30, 3);
cvtColor(edges, frame, COLOR_GRAY2RGB);
}
// image processing example #3
// detect human faces
void cvDetectFaces(Mat &frame)
{
Mat faces;
std::vector<cv::Rect> facesColl;
cvtColor(frame, faces, COLOR_RGB2GRAY);
equalizeHist(faces, faces);
face_cascade.detectMultiScale(faces, facesColl, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, cv::Size(1, 1));
for (unsigned int i = 0; i < facesColl.size(); i++)
{
auto face = facesColl[i];
cv::rectangle(frame, face, cv::Scalar(0, 255, 255), 3);
}
}