Error while detecting faces and apply blur on them - c++

I'm creating an application that capture video stream via webcam and detect the faces and blur them
And this is my code
#include <iostream>
#include <vector>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/features2d/features2d.hpp>
#include <opencv2/objdetect/objdetect.hpp>
using namespace std;
using namespace cv;
int blur_value = 50;
Mat src; Mat dst;
int main(int argc, char* argv[])
{
VideoCapture cap(0);
bool read = true;
char winName[] = "Blured WebCam";
String face_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
if(!cap.isOpened())
{
cout<<"Error while opening your webcam\n";
return 0;
}
for(;;)
{
cap.read(src);
vector <Rect> faces;
Mat blk;
cvtColor( src, blk, COLOR_BGR2GRAY );
equalizeHist( blk, blk );
face_cascade.detectMultiScale( blk, faces, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < faces.size(); i++ )
{
Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
blur( src, dst, Size( faces[i].width/2, faces[i].height/2), Point(-1,-1) );
}
imshow(winName, dst);
switch(waitKey(10))
{
case 27:
return 0;
}
}
return 0;
}
There is no errors in the compilation process, the error comes in when i try to run the application
I got this error
OpenCV Error: Assertion failed (size.width>0 && size.height>0) in
imshow, file
/build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp,
line 269 terminate called after throwing an instance of
'cv::Exception' what():
/build/opencv-SviWsf/opencv-2.4.9.1+dfsg/modules/highgui/src/window.cpp:269:
error: (-215) size.width>0 && size.height>0 in function imshow
Aborted (core dumped)
Where is the problem?

You are probably getting that error when there are no faces detected. If imshow is called on empty frame, it'll give an error. Try this as #miki has suggested
if(!faces.empty()) {
imshow(winName, dst);
}

Related

OpenCV: Unable to run Canny edge detection in C++

I have written a simple code to perform canny edge detection on a live stream. The code is as shown below,
#include <opencv2/imgcodecs.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <iostream>
using namespace cv;
using namespace std;
int lowThreshold=0;
int const max_lowThreshold = 100;
int kernel_size = 3;
int ratio = 3;
Mat img;
Mat display;
void CannyThreshold()
{
cvtColor(img, display, COLOR_RGB2GRAY);
// GaussianBlur(display,display,Size(7,7),3,3);
GaussianBlur(display, display, Size(1, 1), 1,1);
printf("%d\n",lowThreshold);
Canny(display,display,lowThreshold,3);
imshow("Canny",display);
}
int main()
{
VideoCapture cap(0);
namedWindow("Canny");
createTrackbar("Min Threshold: ","Canny",&lowThreshold,max_lowThreshold);
while(1)
{
cap.read(img);
int ret = waitKey(1);
CannyThreshold();
if(ret == 'q')
break;
}
cap.release();
return 0;
}
I get the following run-time error when I run the code. (I'm using OpenCV 4)
error: (-215:Assertion failed) ksize.width > 0 && ksize.width % 2 == 1 && ksize.height > 0 && ksize.height % 2 == 1 in function 'createGaussianKernels'
Any suggestions on how I can solve this error?
The issue is GaussianBlur cant accept kernel size of 1. Correct it to 3x3 or 5x5 in your code as follows
#include <opencv2/core/utility.hpp>
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include <iostream>
#include <ctype.h>
using namespace cv;
using namespace std;
int main(int argc, const char** argv)
{
VideoCapture cap;
Mat frame;
Mat image; // from cap to image
Mat src_gray;
Mat dst;
Mat detected_edges;
const String window_name = "Canny Edge Detector - VideoCapture";
int lowThreshold = 10;
const int max_lowThreshold = 100;
const int ratio = 3;
const int kernel_size = 3;
int FPS;
int frame_width, frame_height;
int camNum = 0;
cap.open(camNum);
if (!cap.isOpened())
{
cout << "***Could not initialize capturing...***\n";
cout << "Current parameter's value: \n";
return -1;
}
FPS = cap.get(CAP_PROP_FPS);
frame_width = cap.get(CAP_PROP_FRAME_WIDTH);
frame_height = cap.get(CAP_PROP_FRAME_HEIGHT);
dst.create(frame_width, frame_height, CV_8UC3);
//cout << CV_8UC3;
while (true)
{
cap >> frame;
if (frame.empty())
break;
frame.copyTo(image);
// Convert the image to grayscale
cvtColor(image, src_gray, COLOR_BGR2GRAY);
//![reduce_noise]
/// Reduce noise with a kernel 3x3
blur(src_gray, detected_edges, Size(3, 3));
//![reduce_noise]
//![canny]
/// Canny detector
Canny(detected_edges, detected_edges, lowThreshold, lowThreshold*ratio, kernel_size);
//![canny]
/// Using Canny's output as a mask, we display our result
//![fill]
dst = Scalar::all(0);
//![fill]
//![copyto]
image.copyTo(dst, detected_edges);
//![copyto]
//![display]
imshow(window_name, dst);
if (waitKey(1000 / FPS) >= 0)
break;
}
return 0;
}

OpenCV Optical Flow Core Dumped

I am using the OpenCV LK Optical Flow example, for some robot vision application with ROS.
It seems to be working reasonably well, however, I am having the error below:
OpenCV Error: Assertion failed ((npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0) in calc, file /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/video/src/lkpyramid.cpp, line 1231
terminate called after throwing an instance of 'cv::Exception'
what(): /build/opencv-L2vuMj/opencv-3.2.0+dfsg/modules/video/src/lkpyramid.cpp:1231: error: (-215) (npoints = prevPtsMat.checkVector(2, CV_32F, true)) >= 0 in function calc
Aborted (core dumped)
As far I could understand by reading the error message, and by the system behavior, it is happening when all of the initial tracking points are gone in the current frame.
There would be a way to restart this process (defining new points) instead of aborting?
My code by the way:
#include <iostream>
#include <opencv2/core.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <opencv2/videoio.hpp>
#include <opencv2/video.hpp>
#include <ros/ros.h>
#include <image_transport/image_transport.h>
#include <cv_bridge/cv_bridge.h>
#include <sensor_msgs/image_encodings.h>
#include <opencv2/imgproc/imgproc.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <vector>
using namespace cv;
using namespace std;
static const std::string OPENCV_WINDOW = "Image_window";
class ImageConverter
{
ros::NodeHandle nh_;
image_transport::ImageTransport it_;
image_transport::Subscriber image_sub_;
image_transport::Publisher image_pub_;
public:
cv::Mat current_frame;
public:
ImageConverter()
: it_(nh_)
{
image_sub_ = it_.subscribe("/realsense/color/image_raw", 1,
&ImageConverter::imageCallback, this);
cv::namedWindow(OPENCV_WINDOW);
}
~ImageConverter()
{
cv::destroyWindow(OPENCV_WINDOW);
}
void imageCallback(const sensor_msgs::ImageConstPtr& msg)
{
cv_bridge::CvImagePtr cv_image;
try
{
cv_image = cv_bridge::toCvCopy(msg, sensor_msgs::image_encodings::BGR8);
current_frame = cv_image->image;
}
catch (cv_bridge::Exception& e)
{
ROS_ERROR("cv_bridge exception: %s", e.what());
return;
}
}
};
int main(int argc, char** argv)
{
ros::init(argc, argv, "OpenCV_Node");
ImageConverter MyNode;
ros::Rate r(30);
r.sleep();
ros::spinOnce();
r.sleep();
// Tentative of Using Open CV Tools with a ROS Image
// Lucas-Kanade Optical Flow from: https://docs.opencv.org/master/d4/dee/tutorial_optical_flow.html
// Create some random colors
vector<Scalar> colors;
RNG rng;
for(int i = 0; i < 100; i++)
{
int r = rng.uniform(0, 256);
int g = rng.uniform(0, 256);
int b = rng.uniform(0, 256);
colors.push_back(Scalar(r,g,b));
}
Mat old_frame, old_gray;
vector<Point2f> p0, p1;
// Take first frame and find corners in it
old_frame = MyNode.current_frame;
cvtColor(old_frame, old_gray, COLOR_BGR2GRAY);
goodFeaturesToTrack(old_gray, p0, 100, 0.3, 7, Mat(), 7, false, 0.04);
// Create a mask image for drawing purposes
Mat mask = Mat::zeros(old_frame.size(), old_frame.type());
//while(true){
while(ros::ok()){
r.sleep();
Mat frame, frame_gray;
frame = MyNode.current_frame;
if (frame.empty())
break;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
// calculate optical flow
vector<uchar> status;
vector<float> err;
TermCriteria criteria = TermCriteria((TermCriteria::COUNT) + (TermCriteria::EPS), 10, 0.03);
calcOpticalFlowPyrLK(old_gray, frame_gray, p0, p1, status, err, Size(15,15), 2, criteria);
vector<Point2f> good_new;
for(uint i = 0; i < p0.size(); i++)
{
// Select good points
if(status[i] == 1) {
good_new.push_back(p1[i]);
// draw the tracks
line(mask,p1[i], p0[i], colors[i], 2);
circle(frame, p1[i], 5, colors[i], -1);
}
}
Mat img;
add(frame, mask, img);
imshow(OPENCV_WINDOW, img);
int keyboard = waitKey(30);
if (keyboard == 'q' || keyboard == 27)
break;
// Now update the previous frame and previous points
old_gray = frame_gray.clone();
p0 = good_new;
ros::spinOnce();
}
return 0;
}

Access Violation Exception Thrown OpenCV

Im working on a simple face detector using Visual Studio 2017 with OpenCV 3.2.0 and haarcascades.
Whenever i run this, i get an error saying there's an exception thrown right after i create the first point. Access violation error. Any help would be greatly appreciated as I do not see any error in the code.
#include <opencv2/opencv.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc/imgproc.hpp>
#include <iostream>
#include <stdio.h>
#include <vector>
using namespace std;
using namespace cv;
int main()
{
CascadeClassifier face_cascade;
CascadeClassifier eye_cascade;
face_cascade.load("haarcascade_frontalface_alt.xml");
eye_cascade.load("haarcascade_eye_tree_eyeglasses.xml");
VideoCapture cap(0);
Mat frame;
while (cap.read(frame))
{
Mat frame_gray;
std::vector <Rect> faces;
cvtColor(frame, frame_gray, COLOR_BGR2GRAY);
equalizeHist(frame_gray, frame_gray);
face_cascade.detectMultiScale(frame_gray,faces, 1.1, 2,0,Size(30,30),Size(300,300));
for (size_t i = 0; i < faces.size();i++)
{
Point first(faces[i].x, faces[i].y);
Point second(faces[i].x + faces[i].width, faces[i].y + faces[i].height);
rectangle(frame,second,first, cvScalar(255, 0, 0), 1, 8, 0);
}
imshow("Test", frame_gray);
waitKey(30);
}
return 0;
}

Capturing the frame when the Object is detected

i have the following code :
#include <iostream>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/objdetect/objdetect.hpp>
#include <opencv2/imgproc/imgproc.hpp>
using namespace std;
using namespace cv;
String object_cascade_name = "haarcascade_frontalface_alt.xml";
CascadeClassifier object_cascade;
string window_name = "Capture - detector";
int main( void )
{
VideoCapture capture;
Mat frame;
std::vector<Rect> objects;
Mat frame_gray;
if( !object_cascade.load( object_cascade_name ) ){ std::cout << "ERROR: Cascade not loaded!\n" ; return -1; };
capture.open( 0 );
if( capture.isOpened() ){
for(;;){
capture >> frame;
capture.retrieve(frame);
//-- 3. Apply the classifier to the frame
if( !frame.empty() ){
// Start
cvtColor( frame, frame_gray, COLOR_BGR2GRAY );
equalizeHist( frame_gray, frame_gray );
//-- Detect Object
object_cascade.detectMultiScale( frame_gray, objects, 1.1, 2, 0|CV_HAAR_SCALE_IMAGE, Size(30, 30) );
for( size_t i = 0; i < objects.size(); i++ ){
Point pt1 = Point( objects[i].x, objects[i].y );
Point pt2 = Point( objects[i].x + objects[i].width, objects[i].y + objects[i].height );
rectangle( frame, pt1, pt2, Scalar( 34, 92, 241 ), 2, 8, 0 );
Mat faceROI = frame_gray( objects[i] );
}
//-- Show what you got
imshow( window_name, frame );
// End
}
else{ std::cout << "ERROR: frame.empty returns 1!"; break; }
int c = waitKey(10);
if( (char)c == 'c' ) { break; }
}
}
return 0;
}
which plays a video from the build-in webcam and detect faces, my idea is that i want the video to stop when an object -face- is detected, then display a window contains the detected object only from the last frame.

binarize image as tif

I have found a program which can binarize an image and make the image monochrome
OpenCV Adaptive Threshold OCR
I have copy/pasted the code
#include <iostream>
#include <vector>
#include <stdio.h>
#include <stdarg.h>
#include "/usr/include/opencv2/opencv.hpp"
#include "fstream"
#include "iostream"
using namespace std;
using namespace cv;
void CalcBlockMeanVariance(Mat& Img,Mat& Res,float blockSide=21) // blockSide - the parameter (set greater for larger font on image)
{
Mat I;
Img.convertTo(I,CV_32FC1);
Res=Mat::zeros(Img.rows/blockSide,Img.cols/blockSide,CV_32FC1);
Mat inpaintmask;
Mat patch;
Mat smallImg;
Scalar m,s;
for(int i=0;i<Img.rows-blockSide;i+=blockSide)
{
for (int j=0;j<Img.cols-blockSide;j+=blockSide)
{
patch=I(Range(i,i+blockSide+1),Range(j,j+blockSide+1));
cv::meanStdDev(patch,m,s);
if(s[0]>0.01) // Thresholding parameter (set smaller for lower contrast image)
{
Res.at<float>(i/blockSide,j/blockSide)=m[0];
}else
{
Res.at<float>(i/blockSide,j/blockSide)=0;
}
}
}
cv::resize(I,smallImg,Res.size());
cv::threshold(Res,inpaintmask,0.02,1.0,cv::THRESH_BINARY);
Mat inpainted;
smallImg.convertTo(smallImg,CV_8UC1,255);
inpaintmask.convertTo(inpaintmask,CV_8UC1);
inpaint(smallImg, inpaintmask, inpainted, 5, INPAINT_TELEA);
cv::resize(inpainted,Res,Img.size());
Res.convertTo(Res,CV_32FC1,1.0/255.0);
}
int main( int argc, char** argv )
{
namedWindow("Img");
namedWindow("Edges");
//Mat Img=imread("D:\\ImagesForTest\\BookPage.JPG",0);
Mat Img=imread("Test2.JPG",0);
Mat res;
Img.convertTo(Img,CV_32FC1,1.0/255.0);
CalcBlockMeanVariance(Img,res);
res=1.0-res;
res=Img+res;
imshow("Img",Img);
cv::threshold(res,res,0.85,1,cv::THRESH_BINARY);
cv::resize(res,res,cv::Size(res.cols/2,res.rows/2));
imwrite("result.jpg",res*255);
imshow("Edges",res);
waitKey(0);
return 0;
}
compile
g++ binarize.cpp `pkg-config opencv --cflags --libs`
run
./a.out
error
(Img:27277): Gtk-WARNING **: cannot open display:
update
int main( int argc, char** argv )
{
namedWindow("Img");
namedWindow("Edges");
//Mat Img=imread("D:\\ImagesForTest\\BookPage.JPG",0);
Mat Img=imread("Test2.JPG",0);
Mat res;
Img.convertTo(Img,CV_32FC1,1.0/255.0);
CalcBlockMeanVariance(Img,res);
res=1.0-res;
res=Img+res;
imshow("Img",Img);
cv::threshold(res,res,0.85,1,cv::THRESH_BINARY);
cv::resize(res,res,cv::Size(res.cols/2,res.rows/2));
imwrite("result.tif",res*255);
imshow("Edges",res);
waitKey(0);
return 0;
}
Just built this code on ubuntu 14.03 x64, using the same command line as you used, no any messages, runs fine.
I think warning related to your system environment.