Face Landmarks and stabilization using optical flow - c++

I write program when window show face and some special points(68).
I use Haar casscade and FaceLandmarkLBF.I have problem in my program. When face have stable position face points are jitter(shaking). How I can fix that? Thanks.
#include <iostream>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/face.hpp>
using cv::Scalar;
using cv::Point;
int main(int argc, char** argv)
{
cv::CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml");
cv::Ptr<cv::face::Facemark>facemark = cv::face::FacemarkLBF::create();
facemark->loadModel("lbfmodel.yaml");
cv::VideoCapture vc(0);
while (true)
{
cv::Mat frame, gray;
vc.read(frame);
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
//
std::vector<cv::Rect> faces;
faceDetector.detectMultiScale(gray, faces);
std::vector< std::vector<cv::Point2f> > landmarks;
bool success = facemark->fit(frame, faces, landmarks);
for (size_t i = 0; i < landmarks.size(); i++)
{
for (size_t j = 0; j < landmarks[i].size(); j++)
{
cv::circle(frame, cv::Point(landmarks[i][j].x, landmarks[i][j].y), 2, Scalar(255, 0, 0), 2);
}
}
cv::imshow("1", frame);
if ((char)cv::waitKey(20) == 27)
break;
}
return 0;
}
I saw #Nuzhny link : lkdemo.cpp. Not everything is clear for me.
I done rewrite my code but nothing changed:
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include "opencv2/video/tracking.hpp"
#include <opencv2/face.hpp>
int main(int argc, char** argv)
{
cv::CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml");
cv::Ptr<cv::face::Facemark>facemark = cv::face::FacemarkLBF::create();
facemark->loadModel("lbfmodel.yaml");
cv::VideoCapture vc(0);
cv::Mat gray, prevGray, image, frame;
cv::Size subPixWinSize(10, 10), winSize(64, 64);
cv::TermCriteria termcrit(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 20, 0.03);
std::vector<uchar> status;
std::vector<float> err;
std::vector<cv::Point2f> oldLandmarks;
std::vector< std::vector<cv::Point2f> > landmarks;
bool b = true;
while (true)
{
vc.read(frame);
cv::cvtColor(frame, gray, cv::COLOR_BGR2GRAY);
std::vector<cv::Rect> faces;
faceDetector.detectMultiScale(gray, faces);
bool success = facemark->fit(frame, faces, landmarks);
if (!success)
{
cv::imshow("1", frame);
continue;
}
if (oldLandmarks.empty())
oldLandmarks = landmarks.front();
if (prevGray.empty())
gray.copyTo(prevGray);
calcOpticalFlowPyrLK(prevGray, gray, landmarks.front(), oldLandmarks, status, err, winSize, 3, termcrit, cv::OPTFLOW_LK_GET_MIN_EIGENVALS, 0.001);
for (size_t i = 0; i < oldLandmarks.size(); i++)
{
cv::circle(frame, cv::Point(oldLandmarks[i].x, oldLandmarks[i].y), 2, cv::Scalar(255, 0, 0), 2);
}
cv::imshow("1", frame);
std::swap(oldLandmarks, landmarks.front());
cv::swap(prevGray, gray);
if ((char)cv::waitKey(20) == 27)
break;
}
return 0;
}

Only LK tracking may be not enough. I'm writing some simple application for correcting landmarks after LK with linear Kalman filter (EDIT 2 - remove prev landmarks):
#include <opencv2/opencv.hpp>
#include <opencv2/face.hpp>
///
class PointState
{
public:
PointState(cv::Point2f point)
:
m_point(point),
m_kalman(4, 2, 0, CV_64F)
{
Init();
}
void Update(cv::Point2f point)
{
cv::Mat measurement(2, 1, CV_64FC1);
if (point.x < 0 || point.y < 0)
{
Predict();
measurement.at<double>(0) = m_point.x; //update using prediction
measurement.at<double>(1) = m_point.y;
m_isPredicted = true;
}
else
{
measurement.at<double>(0) = point.x; //update using measurements
measurement.at<double>(1) = point.y;
m_isPredicted = false;
}
// Correction
cv::Mat estimated = m_kalman.correct(measurement);
m_point.x = static_cast<float>(estimated.at<double>(0)); //update using measurements
m_point.y = static_cast<float>(estimated.at<double>(1));
Predict();
}
cv::Point2f GetPoint() const
{
return m_point;
}
bool IsPredicted() const
{
return m_isPredicted;
}
private:
cv::Point2f m_point;
cv::KalmanFilter m_kalman;
double m_deltaTime = 0.2;
double m_accelNoiseMag = 0.3;
bool m_isPredicted = false;
void Init()
{
m_kalman.transitionMatrix = (cv::Mat_<double>(4, 4) <<
1, 0, m_deltaTime, 0,
0, 1, 0, m_deltaTime,
0, 0, 1, 0,
0, 0, 0, 1);
m_kalman.statePre.at<double>(0) = m_point.x; // x
m_kalman.statePre.at<double>(1) = m_point.y; // y
m_kalman.statePre.at<double>(2) = 1; // init velocity x
m_kalman.statePre.at<double>(3) = 1; // init velocity y
m_kalman.statePost.at<double>(0) = m_point.x;
m_kalman.statePost.at<double>(1) = m_point.y;
cv::setIdentity(m_kalman.measurementMatrix);
m_kalman.processNoiseCov = (cv::Mat_<double>(4, 4) <<
pow(m_deltaTime, 4.0) / 4.0, 0, pow(m_deltaTime, 3.0) / 2.0, 0,
0, pow(m_deltaTime, 4.0) / 4.0, 0, pow(m_deltaTime, 3.0) / 2.0,
pow(m_deltaTime, 3.0) / 2.0, 0, pow(m_deltaTime, 2.0), 0,
0, pow(m_deltaTime, 3.0) / 2.0, 0, pow(m_deltaTime, 2.0));
m_kalman.processNoiseCov *= m_accelNoiseMag;
cv::setIdentity(m_kalman.measurementNoiseCov, cv::Scalar::all(0.1));
cv::setIdentity(m_kalman.errorCovPost, cv::Scalar::all(.1));
}
cv::Point2f Predict()
{
cv::Mat prediction = m_kalman.predict();
m_point.x = static_cast<float>(prediction.at<double>(0));
m_point.y = static_cast<float>(prediction.at<double>(1));
return m_point;
}
};
///
void TrackPoints(cv::Mat prevFrame, cv::Mat currFrame,
const std::vector<cv::Point2f>& currLandmarks,
std::vector<PointState>& trackPoints)
{
// Lucas-Kanade
cv::TermCriteria termcrit(cv::TermCriteria::COUNT | cv::TermCriteria::EPS, 30, 0.01);
cv::Size winSize(7, 7);
std::vector<uchar> status(trackPoints.size(), 0);
std::vector<float> err;
std::vector<cv::Point2f> newLandmarks;
std::vector<cv::Point2f> prevLandmarks;
std::for_each(trackPoints.begin(), trackPoints.end(), [&](const PointState& pts) { prevLandmarks.push_back(pts.GetPoint()); });
cv::calcOpticalFlowPyrLK(prevFrame, currFrame, prevLandmarks, newLandmarks, status, err, winSize, 3, termcrit, 0, 0.001);
for (size_t i = 0; i < status.size(); ++i)
{
if (status[i])
{
trackPoints[i].Update((newLandmarks[i] + currLandmarks[i]) / 2);
}
else
{
trackPoints[i].Update(currLandmarks[i]);
}
}
}
///
int main(int argc, char** argv)
{
cv::CascadeClassifier faceDetector("haarcascade_frontalface_alt2.xml");
cv::Ptr<cv::face::Facemark> facemark = cv::face::FacemarkLBF::create();
facemark->loadModel("lbfmodel.yaml");
cv::VideoCapture cam(0, cv::CAP_DSHOW);
cv::namedWindow("Facial Landmark Detection", cv::WINDOW_NORMAL);
cv::Mat frame;
cv::Mat currGray;
cv::Mat prevGray;
std::vector<PointState> trackPoints;
trackPoints.reserve(68);
while (cam.read(frame))
{
std::vector<cv::Rect> faces;
cv::cvtColor(frame, currGray, cv::COLOR_BGR2GRAY);
faceDetector.detectMultiScale(currGray, faces, 1.1, 3, cv::CASCADE_FIND_BIGGEST_OBJECT);
std::vector<std::vector<cv::Point2f>> landmarks;
bool success = facemark->fit(frame, faces, landmarks);
if (success)
{
if (prevGray.empty())
{
trackPoints.clear();
for (cv::Point2f lp : landmarks[0])
{
trackPoints.emplace_back(lp);
}
}
else
{
if (trackPoints.empty())
{
for (cv::Point2f lp : landmarks[0])
{
trackPoints.emplace_back(lp);
}
}
else
{
TrackPoints(prevGray, currGray, landmarks[0], trackPoints);
}
}
for (const PointState& tp : trackPoints)
{
cv::circle(frame, tp.GetPoint(), 3, tp.IsPredicted() ? cv::Scalar(0, 0, 255) : cv::Scalar(0, 255, 0), cv::FILLED);
}
for (cv::Point2f lp : landmarks[0])
{
cv::circle(frame, lp, 2, cv::Scalar(255, 0, 255), cv::FILLED);
}
}
cv::imshow("Facial Landmark Detection", frame);
if (cv::waitKey(1) == 27)
break;
prevGray = currGray;
}
return 0;
}
So, the margenta points - raw landmarks and green points - corrected after LK+Kalman: result video.
You can change Kalman options with 2 constants:
double m_deltaTime = 0.2;
double m_accelNoiseMag = 0.3;
It's latency and noise.

Related

How reduce false detection in my code and how to improve tracking accuracy with opencv in c++? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 10 months ago.
Improve this question
**Requirements: **
(1) Build OpenCV with Cuda and compile in C++
(2) Version = OpenCV Latest Version
(3) Build and Compile OpenCV Link: https://techawarey.com/programming/install-opencv-c-c-in-ubuntu-18-04-lts-step-by-step-guide/#Summary
(4) Library samples_utility is here: https://github.com/opencv/opencv_contrib/blob/master/modules/tracking/samples/samples_utility.hpp
(4) Compile Program Command: g++ test.cpp -o testoutput -std=c++11 'pkg-config --cflags --libs opencv'
(5) Run Program Command: ./testoutput
Code is working fine but not accurate
Step: 1
Read Frame from Camera
Select ROI(Region of Interest)
After that start KCF tracker with Sobal Features Extractor
Tracking the selected object.
Step: 2
Failure detect
After that call template matching function called MatchingMethod()
Run template matching
Get x, y value from template matching
After that reinitialize KCF tracker with Sobal Features Extractor.
This code is fine for still object when the object is moving the tracker false detection. I want to improve accuracy and reduce false detection.
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/ocl.hpp>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include "sample_utility.hpp"
#include <thread>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iomanip>
#include <stdlib.h>
#include <unistd.h>
//////////////////////////////
using namespace cv;
using namespace std;
////////////////////////////
// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
/// Global Variables
struct Array {
int arr[2];
};
Mat img;
Mat templ;
Mat result_h;
bool flag = true;
int match_method = 5;
int i=0;
int max_Trackbar = 5;
float fps;
int seconds = 0;
// Function Headers
void delay();
// prototype of the functino for feature extractor
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
struct Array MatchingMethod( int, void* );
int main(int argc, char **argv)
{
TrackerKCF::Params param;
param.compress_feature = true;
param.compressed_size = 2;
param.desc_npca = 0;
param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
param.detect_thresh = 0.8;
// create a tracker object
Ptr<TrackerKCF> tracker = TrackerKCF::create(param);
tracker->setFeatureExtractor(sobelExtractor);
VideoCapture cap(0);
// Exit if video is not opened
if(!cap.isOpened())
{
//cout << "Could not read video file" << endl;
return 1;
}
// Read first frame
Mat frame;
bool ok = cap.read(frame);
// Define initial bounding box
//Rect bbox(x, y, w, h);
// Uncomment the line below to select a different bounding box
Rect bbox = selectROI(frame, false);
// Display bounding box.
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
///////////////////////////
int H, W, cW, cH;
// print(f"hight {H} , Width {W}")
H = display_height;
W = display_width;
// Center point of the screen
cW = int(W / 2);
cH = int(H / 2);
Point p1(cW, cH);
// get bounding box
Mat imCrop = frame(bbox);
imwrite("1.png", imCrop);
//quit if ROI was not selected
if(bbox.width==0 || bbox.height==0)
return 0;
//////////////////////////
//imshow("Tracking", frame);
tracker->init(frame, bbox);
while(true)
{
Mat frame;
cap >> frame;
circle(frame, p1, 3, Scalar(0,255,0), -1);
// Start timer
if(bbox.width!=0 || bbox.height!=0){
double timer = (double)getTickCount();
// Update the tracking result
/////////////////////////////////////
bool ok = tracker->update(frame, bbox);
//////////////////////////////////////
//ok, bbox = tracker->update(frame);
// Calculate Frames per second (FPS)
fps = getTickFrequency() / ((double)getTickCount() - timer);
if (ok)
{
// Tracking success : Draw the tracked object
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
///////////////////////////////////////////////////
int xxx, yyy, height, width;
xxx = bbox.x;
yyy = bbox.y;
height = bbox.height;
width = bbox.width;
int diffX, diffY;
float cxROI, cyROI;
cxROI = int((xxx + (xxx + width)) / 2);
cyROI = int((yyy + (yyy + height)) / 2);
diffX = cxROI - cW;
diffY = cH - cyROI;
//cout<<diffX<<"\n";
//cout<<diffY<<"\n";
Point p(cxROI, cyROI);
circle(frame, p, 3, Scalar(128,0,0), -1);
putText(frame, "FPS : " + SSTR(int(fps)), Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);
putText(frame, "Difference From X-Axis: "+SSTR(int(diffX)), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
putText(frame, "Difference From Y-Axis: "+SSTR(int(diffY)), Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
}
else
{
// Tracking failure detected.
putText(frame, "Tracking failure detected", Point(100,110), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(0,0,255),2);
templ = imread( "1.png", 1 );
img=frame.clone();
struct Array a = MatchingMethod( 0, 0 );
cout<<"X: "<<a.arr[0]<<"\n";
cout<<"Y: "<<a.arr[1]<<"\n";
cout<<"Width: "<<w<<"\n";
cout<<"Height: "<<h<<"\n";
int xx, yy, ww, hh;
xx = a.arr[0];
yy = a.arr[1];
ww = w;
hh = h;
Rect bbox(xx, yy, ww, hh);
tracker.release();
tracker = TrackerKCF::create(param);
tracker->setFeatureExtractor(sobelExtractor);
tracker->init(frame, bbox);
//roi.x = MatchingMethod.
//waitKey(30);
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
////////////////////////////////////////////////////////////////////////
int diffX, diffY;
float cxROI, cyROI;
cxROI = int((xx + (xx + ww)) / 2);
cyROI = int((yy + (yy + hh)) / 2);
diffX = cxROI - cW;
diffY = cH - cyROI;
//cout<<diffX<<"\n";
//cout<<diffY<<"\n";
Point p(cxROI, cyROI);
circle(frame, p, 3, Scalar(128,0,0), -1);
///////////////////////////////////////////////////////////////////////////
}
}
else{
}
// Display frame.
imshow("Tracking", frame);
// Exit if ESC pressed.
int k = waitKey(1);
if(k == 27)
{
break;
}
}
return 0;
}
///////////////////////
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
Mat sobel[2];
Mat patch;
Rect region=roi;
// extract patch inside the image
if(roi.x<0){region.x=0;region.width+=roi.x;}
if(roi.y<0){region.y=0;region.height+=roi.y;}
if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
if(region.width>img.cols)region.width=img.cols;
if(region.height>img.rows)region.height=img.rows;
patch=img(region).clone();
cvtColor(patch,patch, COLOR_BGR2GRAY);
// add some padding to compensate when the patch is outside image border
int addTop,addBottom, addLeft, addRight;
addTop=region.y-roi.y;
addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
addLeft=region.x-roi.x;
addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
Sobel(patch, sobel[0], CV_32F,1,0,1);
Sobel(patch, sobel[1], CV_32F,0,1,1);
merge(sobel,2,feat);
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
}
////////////////////////////////////////////////////
struct Array MatchingMethod( int, void* )
{
/// Source image to display
Mat frame;
struct Array a;
/////////
for(int i=1; i<=4; i++){
img.copyTo( frame );
// break;
//}
//////////////////////////
cv::cuda::setDevice(0); // initialize CUDA
// convert from mat to gpumat
cv::cuda::GpuMat image_d(img);
cv::cuda::GpuMat templ_d(templ);
cv::cuda::GpuMat result;
// GPU -> NG
cv::Ptr<cv::cuda::TemplateMatching> alg =
cv::cuda::createTemplateMatching(image_d.type(), cv::TM_CCOEFF_NORMED);
alg->match(image_d, templ_d, result); // no return.
//cv::cuda::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1);
double max_value, min_value;
cv::Point location;
cv::cuda::minMaxLoc(result, &min_value, &max_value, 0, &location);
/////////////////////////
double THRESHOLD = 3e-09; //0.3;
if( min_value <= THRESHOLD) {
//struct Array a;
a.arr[0] = location.x;
a.arr[1] = location.y;
cout<<"Hi"<<endl;
}
}
if(flag==true){
return a;
flag = false;
}
//}
}
Okey here is my answer to your question.
First of all, you are making a mistake by applying template matching when the tracker misses. Because template matching matches the feature if and only if it is totally same with the reference feature. So in your case, there will be shadows, light issues etc. in the environment, and you will never be able to get success results.
Secondly, if you delete the template matching scope, tracker will continue to search the target in the image effectively. Which changements I did in your code is listed below. With these changes, I got better results:
Delete the template matching scope
Decrease the detection threshold(param.detect_thresh) to 0.5
Create more tracker objects to catch the target: This change is the most important part. What I am suggesting is that create more and more tracker objects(in my case I did 4 tracker objects, but you can increase the number). Each tracker should get as input rectangle similar to ROI user chose but not the same coordinates. For example, if user chooses cv::Rect(200,200,400,400) then other tracker should get target as cv::Rect(180,190,400,400) , cv::Rect(220,180,400,400) ... and so on. Why you should do it because, tracker algorithm is feature based, so it will always try to get a similar features to the reference. By doing this, you will increase the feature references.
And here is my code to guide you:
#include <opencv2/core/utility.hpp>
#include <opencv2/tracking.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/core/ocl.hpp>
#include <iostream>
#include <cstring>
#include <unistd.h>
#include <thread>
#include <opencv2/cudaimgproc.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/calib3d.hpp>
#include <opencv2/cudaarithm.hpp>
#include <iomanip>
#include <stdlib.h>
#include <unistd.h>
//////////////////////////////
using namespace cv;
using namespace std;
////////////////////////////
// Convert to string
#define SSTR( x ) static_cast< std::ostringstream & >( \
( std::ostringstream() << std::dec << x ) ).str()
/// Global Variables
struct Array {
int arr[2];
};
Mat img;
Mat templ;
Mat result_h;
bool flag = true;
int match_method = 5;
int i=0;
int max_Trackbar = 5;
float fps;
int seconds = 0;
// Function Headers
void delay();
// prototype of the functino for feature extractor
void sobelExtractor(const Mat img, const Rect roi, Mat& feat);
struct Array MatchingMethod( int, void* );
int main(int argc, char **argv)
{
TrackerKCF::Params param;
param.compress_feature = true;
param.compressed_size = 2;
param.desc_npca = 0;
param.desc_pca = TrackerKCF::GRAY | TrackerKCF::CN;
param.detect_thresh = 0.5;
// create a tracker object
Ptr<TrackerKCF> tracker = TrackerKCF::create(param);
tracker->setFeatureExtractor(sobelExtractor);
Ptr<TrackerKCF> tracker2 = TrackerKCF::create(param);
tracker2->setFeatureExtractor(sobelExtractor);
Ptr<TrackerKCF> tracker3 = TrackerKCF::create(param);
tracker3->setFeatureExtractor(sobelExtractor);
Ptr<TrackerKCF> tracker4 = TrackerKCF::create(param);
tracker4->setFeatureExtractor(sobelExtractor);
VideoCapture cap(0);
// Exit if video is not opened
if(!cap.isOpened())
{
//cout << "Could not read video file" << endl;
return 1;
}
cv::imshow("Tracking",0);
// Read first frame
Mat frame;
bool ok = cap.read(frame);
// Define initial bounding box
//Rect bbox(x, y, w, h);
// Uncomment the line below to select a different bounding box
Rect2d bbox = selectROI(frame, false);
// Display bounding box.
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
///////////////////////////
int H, W, cW, cH;
// print(f"hight {H} , Width {W}")
H = frame.rows;
W = frame.cols;
// Center point of the screen
cW = int(W / 2);
cH = int(H / 2);
Point p1(cW, cH);
//quit if ROI was not selected
if(bbox.width==0 || bbox.height==0)
return 0;
//////////////////////////
//imshow("Tracking", frame);
tracker->init(frame, bbox);
tracker2->init(frame, cv::Rect2d(bbox.x-10,bbox.y-10, bbox.width,bbox.height));
tracker3->init(frame, cv::Rect2d(bbox.x+10,bbox.y+10, bbox.width,bbox.height));
tracker4->init(frame, cv::Rect2d(bbox.x+20,bbox.y+20, bbox.width,bbox.height));
while(true)
{
Mat frame;
cap >> frame;
circle(frame, p1, 3, Scalar(0,255,0), -1);
// Start timer
if(bbox.width!=0 || bbox.height!=0){
double timer = (double)getTickCount();
// Update the tracking result
/////////////////////////////////////
bool ok = tracker->update(frame, bbox);
bool ok2 = tracker->update(frame, bbox);
bool ok3 = tracker->update(frame, bbox);
bool ok4 = tracker->update(frame, bbox);
//////////////////////////////////////
//ok, bbox = tracker->update(frame);
// Calculate Frames per second (FPS)
fps = getTickFrequency() / ((double)getTickCount() - timer);
if (ok || ok2 || ok3 || ok4)
{
// Tracking success : Draw the tracked object
rectangle(frame, bbox, Scalar( 255, 0, 0 ), 2, 1 );
///////////////////////////////////////////////////
int xxx, yyy, height, width;
xxx = bbox.x;
yyy = bbox.y;
height = bbox.height;
width = bbox.width;
int diffX, diffY;
float cxROI, cyROI;
cxROI = int((xxx + (xxx + width)) / 2);
cyROI = int((yyy + (yyy + height)) / 2);
diffX = cxROI - cW;
diffY = cH - cyROI;
//cout<<diffX<<"\n";
//cout<<diffY<<"\n";
Point p(cxROI, cyROI);
circle(frame, p, 3, Scalar(128,0,0), -1);
putText(frame, "FPS : " + SSTR(int(fps)), Point(100,20), FONT_HERSHEY_SIMPLEX, 0.75, Scalar(50,170,50), 2);
putText(frame, "Difference From X-Axis: "+SSTR(int(diffX)), Point(100, 50), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
putText(frame, "Difference From Y-Axis: "+SSTR(int(diffY)), Point(100, 80), FONT_HERSHEY_SIMPLEX, 0.6, Scalar(100, 200, 200), 2);
}
}
else{
}
// Display frame.
imshow("Tracking", frame);
// Exit if ESC pressed.
int k = waitKey(1);
if(k == 27)
{
break;
}
}
return 0;
}
///////////////////////
void sobelExtractor(const Mat img, const Rect roi, Mat& feat){
Mat sobel[2];
Mat patch;
Rect region=roi;
// extract patch inside the image
if(roi.x<0){region.x=0;region.width+=roi.x;}
if(roi.y<0){region.y=0;region.height+=roi.y;}
if(roi.x+roi.width>img.cols)region.width=img.cols-roi.x;
if(roi.y+roi.height>img.rows)region.height=img.rows-roi.y;
if(region.width>img.cols)region.width=img.cols;
if(region.height>img.rows)region.height=img.rows;
patch=img(region).clone();
cvtColor(patch,patch, COLOR_BGR2GRAY);
// add some padding to compensate when the patch is outside image border
int addTop,addBottom, addLeft, addRight;
addTop=region.y-roi.y;
addBottom=(roi.height+roi.y>img.rows?roi.height+roi.y-img.rows:0);
addLeft=region.x-roi.x;
addRight=(roi.width+roi.x>img.cols?roi.width+roi.x-img.cols:0);
copyMakeBorder(patch,patch,addTop,addBottom,addLeft,addRight,BORDER_REPLICATE);
Sobel(patch, sobel[0], CV_32F,1,0,1);
Sobel(patch, sobel[1], CV_32F,0,1,1);
merge(sobel,2,feat);
feat=feat/255.0-0.5; // normalize to range -0.5 .. 0.5
}
////////////////////////////////////////////////////
struct Array MatchingMethod( int, void* )
{
/// Source image to display
Mat frame;
struct Array a;
/////////
for(int i=1; i<=4; i++){
img.copyTo( frame );
// break;
//}
//////////////////////////
cv::cuda::setDevice(0); // initialize CUDA
// convert from mat to gpumat
cv::cuda::GpuMat image_d(img);
cv::cuda::GpuMat templ_d(templ);
cv::cuda::GpuMat result;
// GPU -> NG
cv::Ptr<cv::cuda::TemplateMatching> alg =
cv::cuda::createTemplateMatching(image_d.type(), cv::TM_CCOEFF_NORMED);
alg->match(image_d, templ_d, result); // no return.
//cv::cuda::normalize(result, result, 0, 1, cv::NORM_MINMAX, -1);
double max_value, min_value;
cv::Point location;
cv::cuda::minMaxLoc(result, &min_value, &max_value, 0, &location);
/////////////////////////
double THRESHOLD = 3e-09; //0.3;
if( min_value <= THRESHOLD) {
//struct Array a;
a.arr[0] = location.x;
a.arr[1] = location.y;
cout<<"Hi"<<endl;
}
}
if(flag==true){
return a;
flag = false;
}
//}
}

Every time I run this Code My Raspberry-pi 3b+ reboots

So I'm working on a project to make a robotic car recognize a stop sign and some object and takes actions based on that.
now whenever I run this code It barley open the camera and then I lose connection to the VNC Viewer immediately.
I use 5 Volt, 3 A output power bank.
there is no problem when I run a code to open the camera but only the code below.
#include <opencv2/opencv.hpp>
#include <raspicam_cv.h>
#include <iostream>
#include <chrono>
#include <ctime>
#include <wiringPi.h>
using namespace std;
using namespace cv;
using namespace raspicam;
// Image Processing variables
Mat frame, Matrix, framePers, frameGray, frameThresh, frameEdge, frameFinal, frameFinalDuplicate, frameFinalDuplicate1;
Mat ROILane, ROILaneEnd;
int LeftLanePos, RightLanePos, frameCenter, laneCenter, Result, laneEnd;
RaspiCam_Cv Camera;
stringstream ss;
vector<int> histrogramLane;
vector<int> histrogramLaneEnd;
Point2f Source[] = {Point2f(40,135),Point2f(310,135),Point2f(10,185), Point2f(330,185)};
Point2f Destination[] = {Point2f(100,0),Point2f(280,0),Point2f(100,240), Point2f(280,240)};
//Machine Learning variables
CascadeClassifier Stop_Cascade;
Mat frame_stop;
Mat frame_Stop, RoI_Stop, gray_Stop;
vector<Rect> Stop;
int dist_Stop;
void Setup ( int argc,char **argv, RaspiCam_Cv &Camera )
{
Camera.set ( CAP_PROP_FRAME_WIDTH, ( "-w",argc,argv,400 ) );
Camera.set ( CAP_PROP_FRAME_HEIGHT, ( "-h",argc,argv,240 ) );
Camera.set ( CAP_PROP_BRIGHTNESS, ( "-br",argc,argv,60) );
Camera.set ( CAP_PROP_CONTRAST ,( "-co",argc,argv,70 ) );
Camera.set ( CAP_PROP_SATURATION, ( "-sa",argc,argv,50 ) );
Camera.set ( CAP_PROP_GAIN, ( "-g",argc,argv ,50) );
Camera.set ( CAP_PROP_FPS, ( "-fps",argc,argv,0));
}
void Capture()
{
Camera.grab();
Camera.retrieve( frame);
cvtColor(frame, frame, COLOR_BGR2RGB);
cvtColor(frame, frame_Stop, COLOR_BGR2RGB);
}
void Perspective()
{
line(frame,Source[0], Source[1], Scalar(0,0,255), 2);
line(frame,Source[1], Source[3], Scalar(0,0,255), 2);
line(frame,Source[3], Source[2], Scalar(0,0,255), 2);
line(frame,Source[2], Source[0], Scalar(0,0,255), 2);
Matrix = getPerspectiveTransform(Source, Destination);
warpPerspective(frame, framePers, Matrix, Size(400,240));
}
void Threshold()
{
cvtColor(framePers, frameGray, COLOR_RGB2GRAY);
inRange(frameGray, 240, 255, frameThresh);
Canny(frameGray,frameEdge, 900, 900, 3, false);
add(frameThresh, frameEdge, frameFinal);
cvtColor(frameFinal, frameFinal, COLOR_GRAY2RGB);
cvtColor(frameFinal, frameFinalDuplicate, COLOR_RGB2BGR); //used in histrogram function only
cvtColor(frameFinal, frameFinalDuplicate1, COLOR_RGB2BGR); //used in histrogram function only
}
void Histrogram()
{
histrogramLane.resize(400);
histrogramLane.clear();
for(int i=0; i<400; i++) //frame.size().width = 400
{
ROILane = frameFinalDuplicate(Rect(i,140,1,100));
divide(255, ROILane, ROILane);
histrogramLane.push_back((int)(sum(ROILane)[0]));
}
histrogramLaneEnd.resize(400);
histrogramLaneEnd.clear();
for (int i = 0; i < 400; i++)
{
ROILaneEnd = frameFinalDuplicate1(Rect(i, 0, 1, 240));
divide(255, ROILaneEnd, ROILaneEnd);
histrogramLaneEnd.push_back((int)(sum(ROILaneEnd)[0]));
}
laneEnd = sum(histrogramLaneEnd)[0];
cout<<"Lane END = "<<laneEnd<<endl;
}
void LaneFinder()
{
vector<int>:: iterator LeftPtr;
LeftPtr = max_element(histrogramLane.begin(), histrogramLane.begin() + 150);
LeftLanePos = distance(histrogramLane.begin(), LeftPtr);
vector<int>:: iterator RightPtr;
RightPtr = max_element(histrogramLane.begin() +250, histrogramLane.end());
RightLanePos = distance(histrogramLane.begin(), RightPtr);
line(frameFinal, Point2f(LeftLanePos, 0), Point2f(LeftLanePos, 240), Scalar(0, 255,0), 2);
line(frameFinal, Point2f(RightLanePos, 0), Point2f(RightLanePos, 240), Scalar(0,255,0), 2);
}
void LaneCenter()
{
laneCenter = (RightLanePos-LeftLanePos)/2 +LeftLanePos;
frameCenter = 188;
line(frameFinal, Point2f(laneCenter,0), Point2f(laneCenter,240), Scalar(0,255,0), 3);
line(frameFinal, Point2f(frameCenter,0), Point2f(frameCenter,240), Scalar(255,0,0), 3);
Result = laneCenter-frameCenter;
}
void Stop_detection()
{
if(!Stop_Cascade.load("//home//pi/Desktop//MACHINE LEARNING//Stop_cascade.xml"))
{
printf("Unable to open stop cascade file");
}
RoI_Stop = frame_Stop(Rect(0,0,400,240));
cvtColor(RoI_Stop, gray_Stop, COLOR_RGB2GRAY);
equalizeHist(gray_Stop, gray_Stop);
Stop_Cascade.detectMultiScale(gray_Stop, Stop);
for(int i=0; i<Stop.size(); i++)
{
Point P1(Stop[i].x, Stop[i].y);
Point P2(Stop[i].x + Stop[i].width, Stop[i].x + Stop[i].height);
rectangle(RoI_Stop, P1, P2, Scalar(0, 0, 255), 2);
putText(RoI_Stop, "Stop Sign", P1, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255, 255), 2);
dist_Stop = (-0.91)*(P2.x-P1.x) + 102.597;
ss.str(" ");
ss.clear();
ss<<"D = "<<dist_Stop<<"cm";
putText(RoI_Stop, ss.str(), Point2f(1,130), 0,1, Scalar(0,0,255), 2);
}
}
int main(int argc,char **argv)
{
wiringPiSetup();
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
pinMode(24, OUTPUT);
Setup(argc, argv, Camera);
cout<<"Connecting to camera"<<endl;
if (!Camera.open())
{
cout<<"Failed to Connect"<<endl;
}
cout<<"Camera Id = "<<Camera.getId()<<endl;
while(1)
{
auto start = std::chrono::system_clock::now();
Capture();
Perspective();
Threshold();
Histrogram();
LaneFinder();
LaneCenter();
Stop_detection();
if (laneEnd > 6000)
{
digitalWrite(21, 1);
digitalWrite(22, 1); //decimal = 7
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Lane End"<<endl;
}
if (Result == 0)
{
digitalWrite(21, 0);
digitalWrite(22, 0); //decimal = 0
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Forward"<<endl;
}
else if (Result >0 && Result <10)
{
digitalWrite(21, 1);
digitalWrite(22, 0); //decimal = 1
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right1"<<endl;
}
else if (Result >=10 && Result <20)
{
digitalWrite(21, 0);
digitalWrite(22, 1); //decimal = 2
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right2"<<endl;
}
else if (Result >20)
{
digitalWrite(21, 1);
digitalWrite(22, 1); //decimal = 3
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right3"<<endl;
}
else if (Result <0 && Result >-10)
{
digitalWrite(21, 0);
digitalWrite(22, 0); //decimal = 4
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left1"<<endl;
}
else if (Result <=-10 && Result >-20)
{
digitalWrite(21, 1);
digitalWrite(22, 0); //decimal = 5
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left2"<<endl;
}
else if (Result <-20)
{
digitalWrite(21, 0);
digitalWrite(22, 1); //decimal = 6
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left3"<<endl;
}
if (laneEnd > 6000)
{
ss.str(" ");
ss.clear();
ss<<" Lane End";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(255,0,0), 2);
}
else if (Result == 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Forward";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
else if (Result > 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Right";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
else if (Result < 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Left";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
namedWindow("orignal", WINDOW_KEEPRATIO);
moveWindow("orignal", 0, 100);
resizeWindow("orignal", 640, 480);
imshow("orignal", frame);
namedWindow("Perspective", WINDOW_KEEPRATIO);
moveWindow("Perspective", 640, 100);
resizeWindow("Perspective", 640, 480);
imshow("Perspective", framePers);
namedWindow("Final", WINDOW_KEEPRATIO);
moveWindow("Final", 1280, 100);
resizeWindow("Final", 640, 480);
imshow("Final", frameFinal);
namedWindow("Stop Sign", WINDOW_KEEPRATIO);
moveWindow("Stop Sign", 1280, 580);
resizeWindow("Stop Sign", 640, 480);
imshow("Stop Sign", RoI_Stop);
waitKey(1);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
// float t = elapsed_seconds.count();
// int FPS = 1/t;
// cout<<"FPS = "<<FPS<<endl;
}
return 0;
}

Is there a way to adjust the brightness and contrast automatically depending on the surrounding in openCV C++?

The pi camera detects the objects but it does not recognize them if the brightness or the contrast differ because of the location. It is a pi car so the location changes a lot and so the intensity of light in the room. Is there a code that can adjust the brightness/contrast of the pi camera while it's moving (not as a picture)?
#include <opencv2/opencv.hpp>
#include <raspicam_cv.h>
#include <iostream>
#include <chrono>
#include <ctime>
#include <wiringPi.h>
using namespace std;
using namespace cv;
using namespace raspicam;
// Image Processing variables
Mat frame, Matrix, framePers, frameGray, frameThresh, frameEdge, frameFinal, frameFinalDuplicate, frameFinalDuplicate1;
Mat ROILane, ROILaneEnd;
int LeftLanePos, RightLanePos, frameCenter, laneCenter, Result, laneEnd;
RaspiCam_Cv Camera;
stringstream ss;
vector<int> histrogramLane;
vector<int> histrogramLaneEnd;
Point2f Source[] = {Point2f(75,170),Point2f(335,170),Point2f(45,220), Point2f(355,220)};
Point2f Destination[] = {Point2f(100,0),Point2f(280,0),Point2f(100,240), Point2f(280,240)};
//Machine Learning variables
CascadeClassifier Stop_Cascade, Arrow_Cascade;
Mat frame_Stop, RoI_Stop, gray_Stop, frame_Arrow, RoI_Arrow, gray_Arrow;
vector<Rect> Stop, Arrow;
int dist_Stop, dist_Arrow;
void Setup ( int argc,char **argv, RaspiCam_Cv &Camera )
{
Camera.set ( CAP_PROP_FRAME_WIDTH, ( "-w",argc,argv,400 ) );
Camera.set ( CAP_PROP_FRAME_HEIGHT, ( "-h",argc,argv,240 ) );
Camera.set ( CAP_PROP_BRIGHTNESS, ( "-br",argc,argv,55) );
Camera.set ( CAP_PROP_CONTRAST ,( "-co",argc,argv,80 ) );
Camera.set ( CAP_PROP_SATURATION, ( "-sa",argc,argv,50 ) );
Camera.set ( CAP_PROP_GAIN, ( "-g",argc,argv ,50) );
Camera.set ( CAP_PROP_FPS, ( "-fps",argc,argv,0));
}
void Capture()
{
Camera.grab();
Camera.retrieve( frame);
cvtColor(frame, frame_Stop, COLOR_BGR2RGB);
cvtColor(frame, frame_Arrow, COLOR_BGR2RGB);
cvtColor(frame, frame, COLOR_BGR2RGB);
}
void Perspective()
{
line(frame,Source[0], Source[1], Scalar(0,0,255), 2);
line(frame,Source[1], Source[3], Scalar(0,0,255), 2);
line(frame,Source[3], Source[2], Scalar(0,0,255), 2);
line(frame,Source[2], Source[0], Scalar(0,0,255), 2);
Matrix = getPerspectiveTransform(Source, Destination);
warpPerspective(frame, framePers, Matrix, Size(400,240));
}
void Threshold()
{
cvtColor(framePers, frameGray, COLOR_RGB2GRAY);
inRange(frameGray, 240, 255, frameThresh);
Canny(frameGray,frameEdge, 900, 900, 3, false);
add(frameThresh, frameEdge, frameFinal);
cvtColor(frameFinal, frameFinal, COLOR_GRAY2RGB);
cvtColor(frameFinal, frameFinalDuplicate, COLOR_RGB2BGR); //used in histrogram function only
cvtColor(frameFinal, frameFinalDuplicate1, COLOR_RGB2BGR); //used in histrogram function only
}
void Histrogram()
{
histrogramLane.resize(400);
histrogramLane.clear();
for(int i=0; i<400; i++) //frame.size().width = 400
{
ROILane = frameFinalDuplicate(Rect(i,140,1,100));
divide(255, ROILane, ROILane);
histrogramLane.push_back((int)(sum(ROILane)[0]));
}
histrogramLaneEnd.resize(400);
histrogramLaneEnd.clear();
for (int i = 0; i < 400; i++)
{
ROILaneEnd = frameFinalDuplicate1(Rect(i, 0, 1, 240));
divide(255, ROILaneEnd, ROILaneEnd);
histrogramLaneEnd.push_back((int)(sum(ROILaneEnd)[0]));
}
laneEnd = sum(histrogramLaneEnd)[0];
cout<<"Lane END = "<<laneEnd<<endl;
}
void LaneFinder()
{
vector<int>:: iterator LeftPtr;
LeftPtr = max_element(histrogramLane.begin(), histrogramLane.begin() + 150);
LeftLanePos = distance(histrogramLane.begin(), LeftPtr);
vector<int>:: iterator RightPtr;
RightPtr = max_element(histrogramLane.begin() +250, histrogramLane.end());
RightLanePos = distance(histrogramLane.begin(), RightPtr);
line(frameFinal, Point2f(LeftLanePos, 0), Point2f(LeftLanePos, 240), Scalar(0, 255,0), 2);
line(frameFinal, Point2f(RightLanePos, 0), Point2f(RightLanePos, 240), Scalar(0,255,0), 2);
}
void LaneCenter()
{
laneCenter = (RightLanePos-LeftLanePos)/2 +LeftLanePos;
frameCenter = 188;
line(frameFinal, Point2f(laneCenter,0), Point2f(laneCenter,240), Scalar(0,255,0), 3);
line(frameFinal, Point2f(frameCenter,0), Point2f(frameCenter,240), Scalar(255,0,0), 3);
Result = laneCenter-frameCenter;
}
void Stop_detection()
{
if(!Stop_Cascade.load("//home//pi/Desktop//MACHINE LEARNING//Stop_cascade.xml"))
{
printf("Unable to open stop cascade file");
}
RoI_Stop = frame_Stop(Rect(0,0,400,240));
cvtColor(RoI_Stop, gray_Stop, COLOR_RGB2GRAY);
equalizeHist(gray_Stop, gray_Stop);
Stop_Cascade.detectMultiScale(gray_Stop, Stop);
for(int i=0; i<Stop.size(); i++)
{
Point P1(Stop[i].x, Stop[i].y);
Point P2(Stop[i].x + Stop[i].width, Stop[i].x + Stop[i].height);
rectangle(RoI_Stop, P1, P2, Scalar(0, 0, 255), 2);
putText(RoI_Stop, "Stop Sign", P1, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255, 255), 2);
dist_Stop = (-0.91)*(P2.x-P1.x) + 71.86;
ss.str(" ");
ss.clear();
ss<<"D = "<<dist_Stop<<"cm";
putText(RoI_Stop, ss.str(), Point2f(1,130), 0,1, Scalar(0,0,255), 2);
}
}
void Arrow_detection()
{
if(!Arrow_Cascade.load("//home//pi/Desktop//MACHINE LEARNING//Arrow_cascade.xml"))
{
printf("Unable to open Arrow cascade file");
}
RoI_Arrow = frame_Arrow(Rect(0,0,400,240));
cvtColor(RoI_Arrow, gray_Arrow, COLOR_RGB2GRAY);
equalizeHist(gray_Arrow, gray_Arrow);
Arrow_Cascade.detectMultiScale(gray_Arrow, Arrow);
for(int i=0; i<Arrow.size(); i++)
{
Point P1(Arrow[i].x, Arrow[i].y);
Point P2(Arrow[i].x + Arrow[i].width, Arrow[i].x + Arrow[i].height);
rectangle(RoI_Arrow, P1, P2, Scalar(0, 0, 255), 2);
putText(RoI_Arrow, "Arrow", P1, FONT_HERSHEY_PLAIN, 1, Scalar(0, 0, 255, 255), 2);
dist_Arrow = (-1)*(P2.x-P1.x) + 82;
ss.str(" ");
ss.clear();
ss<<"D = "<<dist_Arrow <<"cm";
putText(RoI_Arrow, ss.str(), Point2f(1,130), 0,1, Scalar(0,0,255), 2);
}
}
int main(int argc,char **argv)
{
wiringPiSetup();
pinMode(21, OUTPUT);
pinMode(22, OUTPUT);
pinMode(23, OUTPUT);
pinMode(24, OUTPUT);
Setup(argc, argv, Camera);
cout<<"Connecting to camera"<<endl;
if (!Camera.open())
{
cout<<"Failed to Connect"<<endl;
}
cout<<"Camera Id = "<<Camera.getId()<<endl;
while(1)
{
auto start = std::chrono::system_clock::now();
Capture();
Perspective();
Threshold();
Histrogram();
LaneFinder();
LaneCenter();
Stop_detection();
Arrow_detection();
if (dist_Stop > 5 && dist_Stop < 30)
{
digitalWrite(21, 0);
digitalWrite(22, 0); //decimal = 8
digitalWrite(23, 0);
digitalWrite(24, 1);
cout<<"Stop Sign"<<endl;
dist_Stop = 0;
goto Stop_Sign;
}
if (laneEnd > 6000)
{
digitalWrite(21, 1);
digitalWrite(22, 1); //decimal = 7
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Lane End"<<endl;
}
if (Result == 0)
{
digitalWrite(21, 0);
digitalWrite(22, 0); //decimal = 0
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Forward"<<endl;
}
else if (Result >0 && Result <10)
{
digitalWrite(21, 1);
digitalWrite(22, 0); //decimal = 1
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right1"<<endl;
}
else if (Result >=10 && Result <20)
{
digitalWrite(21, 0);
digitalWrite(22, 1); //decimal = 2
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right2"<<endl;
}
else if (Result >20)
{
digitalWrite(21, 1);
digitalWrite(22, 1); //decimal = 3
digitalWrite(23, 0);
digitalWrite(24, 0);
cout<<"Right3"<<endl;
}
else if (Result <0 && Result >-10)
{
digitalWrite(21, 0);
digitalWrite(22, 0); //decimal = 4
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left1"<<endl;
}
else if (Result <=-10 && Result >-20)
{
digitalWrite(21, 1);
digitalWrite(22, 0); //decimal = 5
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left2"<<endl;
}
else if (Result <-20)
{
digitalWrite(21, 0);
digitalWrite(22, 1); //decimal = 6
digitalWrite(23, 1);
digitalWrite(24, 0);
cout<<"Left3"<<endl;
}
Stop_Sign:
if (laneEnd > 7000)
{
ss.str(" ");
ss.clear();
ss<<" Lane End";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(255,0,0), 2);
}
else if (Result == 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Forward";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
else if (Result > 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Right";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
else if (Result < 0)
{
ss.str(" ");
ss.clear();
ss<<"Result = "<<Result<<" Move Left";
putText(frame, ss.str(), Point2f(1,50), 0,1, Scalar(0,0,255), 2);
}
namedWindow("orignal", WINDOW_KEEPRATIO);
moveWindow("orignal", 0, 100);
resizeWindow("orignal", 420, 300);
imshow("orignal", frame);
namedWindow("Perspective", WINDOW_KEEPRATIO);
moveWindow("Perspective", 400, 100);
resizeWindow("Perspective", 420, 300);
imshow("Perspective", framePers);
namedWindow("Final", WINDOW_KEEPRATIO);
moveWindow("Final", 800, 100);
resizeWindow("Final", 420, 300);
imshow("Final", frameFinal);
namedWindow("Stop Sign", WINDOW_KEEPRATIO);
moveWindow("Stop Sign", 1200, 100);
resizeWindow("Stop Sign", 420, 300);
imshow("Stop Sign", RoI_Stop);
namedWindow("Arrow", WINDOW_KEEPRATIO);
moveWindow("Arrow", 1200, 450);
resizeWindow("Arrow", 420, 300);
imshow("Arrow", RoI_Arrow);
waitKey(1);
auto end = std::chrono::system_clock::now();
std::chrono::duration<double> elapsed_seconds = end-start;
float t = elapsed_seconds.count();
int FPS = 1/t;
// cout<<"FPS = "<<FPS<<endl;
}
return 0;
}

Open CV Harris Corner Detection

I have created a simple class to detect corners using
harris algorithm
. it is working but when I change the threshold value using trackbar and when the value is getting low (below 100) then the process is stopped.
this is my sample code.
my header file
class CornerCapturer{
struct configValues
{
int block;
int k_size;
int thre;
double k;
configValues() :block(2), k_size(3), thre(100), k(0.04){}
};
public:
static configValues conf;
void captureCorners();
static void captevent(int, void*);
Mat captureCornerPoints(int thresh, int block, int k_size, double k, Mat frame);
};
my Cpp file
void CaptureBall::detectCorners(){
CornerCapturer capt;
VideoCapture cap = capture.captureVideo();
cap.read(frame);
capt.captureCorners();
for (;;){
cap.read(frame);
capt.captevent(0, 0);
waitKey(5);
}
}
void CornerCapturer::captureCorners(){
int *t = &CornerCapturer::conf.thre;
namedWindow("Open", CV_WINDOW_AUTOSIZE);
captevent(0, 0);
createTrackbar("Thresh", "Open", t, 255, CornerCapturer::captevent);
}
void CornerCapturer::captevent(int, void*){
Mat res;
CornerCapturer cap;
res = cap.captureCornerPoints(CornerCapturer::conf.thre, CornerCapturer::conf.block, CornerCapturer::conf.k_size, CornerCapturer::conf.k, frame);
imshow("Open", res);
}
Mat CornerCapturer::captureCornerPoints(int thresh, int block, int k_size, double k, Mat f){
Mat gray, corner_detected, cnv_normal,copy;
copy = f;
cvtColor(copy, gray, COLOR_RGB2GRAY); // convert to gray image
cornerHarris(gray, corner_detected, block, k_size, k, BORDER_DEFAULT); // detect cornet points
normalize(corner_detected, cnv_normal, 0, 255, NORM_MINMAX, CV_32FC1, Mat()); // normalize image
for (int j = 0; j < cnv_normal.rows; j++)
{
for (int i = 0; i < cnv_normal.cols; i++)
{
if ((int)cnv_normal.at<float>(j, i) > thresh)
{
circle(copy, Point(i, j), 8, Scalar(120), 2, 8, 0); // put points
}
}
}
return copy;
}
i used OpenCV library for track corners

How to display the final decision for face detection using opencv

I am a beginner of using opencv. I using opencv 2.4 with VS2013. I had develop face detection code and success but the decision made is from frame by frame. How can I made final decision by combining all the frame or frame averaging?? For example, when the total face detected is 90% detected, the final decision is 'FACE DETECTED' and vice versa.
Here is my code:
int main(int argc, char** argv)
{
CvCapture* capture;
capture = cvCaptureFromFile("C:/Users/user/Desktop/Face and Motion/45.avi");
//assert(capture != NULL); //terminate if capture is NULL
IplImage* frame;
while (true)
{
frame = cvQueryFrame(capture);
if (!frame)
break;
cvShowImage("original", frame); //show
CvMemStorage* storage = cvCreateMemStorage(0);
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml");
cvClearMemStorage(storage);
CvSeq* faces = cvHaarDetectObjects(frame, cascade, storage, 1.1, 4, 0, cvSize(40, 50));
CvRect* r;
if (faces) //change from (!faces) to (faces)
{
for (int i = 0; i < (faces ? faces->total : 0); i++)
{
r = (CvRect*)cvGetSeqElem(faces, i);
//cvRectangle(frame, cvPoint(100, 50), cvPoint(200, 200), CV_RGB(255, 0, 0), 5, 8);
cvRectangle(frame, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), CV_RGB(255, 0, 0));
cvShowImage("RESULTS", frame);
char c = cvWaitKey(1000);
}
}
else
{
cvShowImage("RESULT", frame);
}
printf("%d Face Found !\n", faces ? faces->total : 0);
if ((faces ? faces->total : 0) == 0)
{
printf("FACE NOT DETECTED !\n\n");
}
else
{
printf("FACE DETECTED !\n\n");
}
}
return (0);
}
you need two variables like
int frame_count = 0;
int detected_face_count = 0;
you should increase frame_count for every frame and increase detected_face_count when a face detected. finally detected_face_count / frame_count gives your desired value.
however, i did some corrections on your code (i could not test it)
changes explained by comments. i hope it will be useful.
int main(int argc, char** argv)
{
CvCapture* capture;
capture = cvCaptureFromFile("C:/Users/user/Desktop/Face and Motion/45.avi");
//assert(capture != NULL); //terminate if capture is NULL
IplImage* frame;
//you need two variables
int frame_count = 0;
int detected_face_count = 0;
// these lines should not be in the loop
CvMemStorage* storage = cvCreateMemStorage(0);
CvHaarClassifierCascade* cascade = (CvHaarClassifierCascade*)cvLoad("C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml");
while (true)
{
frame = cvQueryFrame(capture);
if (!frame)
break;
frame_count++; // increase frame_count
cvShowImage("original", frame); //show
cvClearMemStorage(storage);
CvSeq* faces = cvHaarDetectObjects(frame, cascade, storage, 1.1, 4, 0, cvSize(40, 50));
CvRect* r;
for (int i = 0; i < (faces ? faces->total : 0); i++)
{
r = (CvRect*)cvGetSeqElem(faces, i);
//cvRectangle(frame, cvPoint(100, 50), cvPoint(200, 200), CV_RGB(255, 0, 0), 5, 8);
cvRectangle(frame, cvPoint(r->x, r->y), cvPoint(r->x + r->width, r->y + r->height), CV_RGB(255, 0, 0));
}
cvShowImage("RESULT", frame);
char c = cvWaitKey(1000);
printf("%d Face Found !\n", faces ? faces->total : 0);
if ((faces ? faces->total : 0) == 0)
{
printf("FACE NOT DETECTED !\n\n");
}
else
{
detected_face_count ++; // increase detected_face_count
printf("FACE DETECTED !\n\n");
}
}
if( (float)(detected_face_count / frame_count) > 0.89 )
{
printf("FACES DETECTED over %90 of frames!\n\n");
}
return (0);
}
as #Miki stated you should not use deprecated C api
take a look at the code below using C++ api (tested with OpenCV 3.1)
#include <opencv2/opencv.hpp>
using namespace cv;
using namespace std;
int main(int argc, char** argv)
{
VideoCapture capture("C:/Users/user/Desktop/Face and Motion/45.avi");
if(!capture.isOpened())
{
printf("Video file could not be opened !\n");
return -1;
}
Mat frame;
//you need two variables
int frame_count = 0;
int detected_face_count = 0;
// these lines should not be in the loop
CascadeClassifier cascade;
if( !cascade.load( "C:/opencv2410/sources/data/haarcascades/haarcascade_frontalface_alt.xml" ) )
{
cerr << "ERROR: Could not load classifier cascade" << endl;
return -1;
}
while (true)
{
capture >>frame;
if (frame.empty())
break;
frame_count++; // increase frame_count
imshow("original", frame); //show
vector<Rect> faces;
cascade.detectMultiScale(frame, faces,1.1, 4, 0, Size(40, 50));
for (int i = 0; i < faces.size(); i++)
{
rectangle(frame, faces[i], Scalar(0, 0, 255));
}
imshow("RESULT", frame);
char c = waitKey(10);
printf("%d Face Found !\n", faces.size());
if ( faces.size() == 0 )
{
printf("FACE NOT DETECTED !\n\n");
}
else
{
detected_face_count ++; // increase detected_face_count
printf("FACE DETECTED !\n\n");
}
}
printf("count of frames : %d \n", frame_count);
printf("count of frames has detected face : %d \n", detected_face_count);
printf("Face Found %d percent of frames!\n", (int)(100 * detected_face_count / frame_count));
if( (float)(detected_face_count / frame_count) > 0.89 )
{
printf("FACES DETECTED over %90 of frames!\n\n");
}
return (0);
}