Comparing current and previous faces from a continous faces detection - c++

I am working with face detection.I need to compare current and previous(successive) faces.Can any one help me how to take current and previous faces from a continuous face detection.I am not getting any idea about this.
This is my face detection code
void facedetect(IplImage* image)
{
ct1++;
cvNamedWindow("output");
int j=0,i,count=0,strsize;
char numstr[50];
CvPoint ul,lr,w,h,ul1,lr1;
CvRect *r;
string path;
IplImage* image1;IplImage* tmpsize;IplImage* reimg;
CvHaarClassifierCascade* cascade=(CvHaarClassifierCascade*) cvLoad(cascade_name);
CvMemStorage* storage=cvCreateMemStorage(0);
const char *extract;
if(!cascade)
{
cout<<"Coulid not load classifier cascade"<<endl;
}
if(cascade)
{ faces=cvHaarDetectObjects(image,cascade,storage,1.1,1,CV_HAAR_DO_CANNY_PRUNING,cvSize(10,10));
for(int i=0;i<(faces ? faces->total : 0);i++)
{
string s1="im",re,rename,ex=".pgm";
sprintf(numstr, "%d", k);
re = s1 + numstr;
rename=re+ex;
char *extract1=new char[rename.size()+1];
extract1[rename.size()]=0; memcpy(extract1,rename.c_str(),rename.size());
strsize=rename.size();
r=(CvRect*) cvGetSeqElem(faces,i);
ul.x=r->x;
ul.y=r->y;
w.x=r->width;
h.y=r->height;
lr.x=(r->x + r->width);
lr.y=(r->y + r->height);
cvSetImageROI(image,cvRect(ul.x,ul.y,w.x,h.y));
image1=cvCreateImage(cvGetSize(image),image->depth,image->nChannels);
cvCopy(image, image1, NULL);
reimg=resizeImage(image1, 40, 40, true);
saveImage(reimg,extract1);
Mat img=cvarrToMat(reimg);
//Mat img1=cvarrToMat();
imshow("result",img); //this is the current image, but i need to get the previous image also.
//readImag(img,"/home/athira/Image/folderr", path);
cvResetImageROI(image);
cvRectangle(image,ul,lr,CV_RGB(1,255,0),3,8,0);
j++,count++;
k++;
arr[l]=ul.x;
arr1[l]=ul.y;
cout<<"frame"<<ct1<<" "<<"face"<<ct<<":"<<"x: "<<ul.x<<endl;
cout<<"frame"<<ct1<<" "<<"face"<<ct<<":"<<"y: "<<ul.y<<endl;
cout<<""<<endl;
ct++;
//compareImages(l,faces->total);
//feature_extract(img,img1);
l++;
}
width=image->width;
height=image->height;
resoltion=width*height;
s=(float) 0.0301/100;
diff=s*resoltion;
cvShowImage("output",image);
cvWaitKey(0);
}
}

Related

OpenCV Both RANSAC and LMeDS making an essential matrix of size 0

I was trying to use the findEssentialMat function to produce an essential matrix and kept getting an empty matrix, even with very low probability and high threshold values. I made reproduceable code that tries to compute the essential matrix from a still image, and I still get no essential matrix. I'm not sure why this is happening.
Code:
int main(int argc, char** argv) {
Mat in = imread("test.jpg", IMREAD_GRAYSCALE);
std::vector<KeyPoint> keypoints;
std::vector<Point2f> points;
std::vector<Point2f> prevPoints;
std::vector<uchar> status;
points = featureDetection(in, keypoints, 30);
prevPoints = std::vector<Point2f>(points);
double focal = 0;
Point2d opticalCenter(in.rows / 2, in.cols / 2);
// Track features
featureTracking(in, in, points, prevPoints, status);
// FIXME RANSAC algorithm not working. Try LMEDS?
Mat E, mask;
E = findEssentialMat(points, prevPoints, focal, opticalCenter, RANSAC, 0.001, 100.0, mask);
Mat R, t;
if(E.size().area() == 0) {
std::cout << mask.size().area() << " points, essential matrix is empty\n";
} else {
recoverPose(E, points, prevPoints, R, t, focal, opticalCenter, mask);
}
// Draw tracked features (this frame)
for(int i = 0; i < prevPoints.size(); i++) {
// Tracking lines
line(in, points[i], prevPoints[i], Scalar(0, 100, 0), 5, LineTypes::LINE_4);
}
// Show output
imshow("Data", in);
char c = waitKey(0);
imwrite("out.jpg", in);
std::vector<Point2f> featureDetection(const Mat& imgIn, std::vector<KeyPoint>& pointsOut, int threshold) {
bool nonmaxSuppression = true;
FAST(imgIn, pointsOut, threshold, nonmaxSuppression);
std::vector<Point2f> points(0);
for(KeyPoint p : pointsOut) {
points.push_back(p.pt);
}
return points;
}
void featureTracking(const Mat& img_1, const Mat& img_2, std::vector<Point2f>& points1, std::vector<Point2f>& points2, std::vector<uchar>& status) {
//this function automatically gets rid of points for which tracking fails
std::vector<float> err;
Size winSize=Size(21,21);
TermCriteria termcrit=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01);
cv::calcOpticalFlowPyrLK(img_1, img_2, points1, points2, status, err, winSize, 3, termcrit, 0, 0.001);
//getting rid of points for which the KLT tracking failed or those who have gone outside the frame
int indexCorrection = 0;
for( int i=0; i<status.size(); i++) {
Point2f pt = points2.at(i- indexCorrection);
if ((status.at(i) == 0)||(pt.x<0)||(pt.y<0)) {
if((pt.x<0)||(pt.y<0)) {
status.at(i) = 0;
}
points1.erase (points1.begin() + i - indexCorrection);
points2.erase (points2.begin() + i - indexCorrection);
indexCorrection++;
}
}
}
Input:
Output (Markers denoted by *):
I'm using OpenCV 4.5.4 built for MinGW
It looks like the findEssentialMat function does not work with a focal length of 0, setting it to 1 fixed the issue!

Invalid resolution dpi. tesseract

I have made some changes to an image such as histogram, dilation, gray scale, edge detection etc. to identify the number plate in an image.The below code is part of where i slice each charterer in the number plate and storing it in Mat. Now I'd like to use tesseract to identify each character. but instead tesseract throw this warning. " Warning. Invalid resolution 0 dpi. Using 70 instead." and OCR output is empty. Can anyone help me.
Note: for now i'm doing only for one pic. just to check whether is it working or not.
if (!Plate.empty())
{
imshow("Final Plate", Plate);
waitKey();
int x = OTSU(Plate);
Mat BlurBinary = ConvertToBinary(Plate, x);
Mat BinPlate = BlurBinary.clone();
imshow("BinaryBlurImg", BlurBinary);
waitKey();
vector<vector<Point>>contours2;
vector<Vec4i>hierachy2;
findContours(BlurBinary, contours2, hierachy2, RETR_EXTERNAL, CHAIN_APPROX_NONE, Point(0, 0));
Mat dst1 = Mat::zeros(BlurBinary.size(), CV_8UC3);
if (!contours1.empty()) {
int i = 0;
for (int i = 0; i < contours2.size(); i++) {
Scalar color((rand() & 255), (rand() & 255), (rand() & 255));
drawContours(dst1, contours2, i, color, CV_FILLED, 8, hierachy2);
}
}
Rect BlobRect2;
for (int i = 0; i < contours2.size(); i++) {
BlobRect2 = boundingRect(contours2[i]);
if (BlobRect2.height < 10)
{
drawContours(BinPlate, contours2, i, black, CV_FILLED, 8, hierachy2);
}
else
{
Mat character;
character = Plate(BlobRect2);
imshow("character", character);
waitKey();
imwrite(format("C:/Users/Di/source/repos/LPRrecognition/Characters/Img%d.tif", i), character);
}
}
}
else {
cout << "no plate sorry";
}
char *outText;
tesseract::TessBaseAPI *api = new tesseract::TessBaseAPI();
// Initialize tesseract-ocr with English, without specifying tessdata path
if (api->Init(NULL, "eng")) {
fprintf(stderr, "Could not initialize tesseract.\n");
exit(1);
}
// Open input image with leptonica library
Pix *image1 = pixRead("C:\\Users\\Di\\source\\repos\\LPRrecognition\\Characters\\Img1.tif");
api->SetImage(image1);
// Get OCR result
outText = api->GetUTF8Text();
printf("OCR output:\n%s", outText);
cout << outText;
// Destroy used object and release memory
api->End();
delete[] outText;
pixDestroy(&image1);

Object tracking delay color tracking OpenCV

I am trying to detect colored balls like ps3 move controller balls from 2 mt distance.I have 10 camera in same room hanging from the ceiling.Room is dark and balls have led inside.I have 4-5 balls.(red,blue,green,yellow,pink). I want track their position with opencv.Whats the right mehtod for doing this in opencv ? Can u give link , example for this ?
I use this code but i have delay problem.When i comment // my trackFilteredObject line there is no lag.But when using this code i have lot latency.I cant understand why happening because my normal cpu usage ~%15 ram usage 6.3GB/15GB (%40) when run this code cpu usage ~20-23 ram usage 6.4GB . I think its not about cpu-ram performance.What am i doing wrong ?
Video: https://www.youtube.com/watch?v=_BKtJpPrkO4 (You can see lag in first 10 sec.After 10 sen i comment tracking codes.)
Note:Kamerasayisi mean cameracount My Track Function:
void trackFilteredObject(Object theObject,Mat threshold,Mat HSV, Mat &cameraFeed){
//max number of objects to be detected in frame
const int FRAME_WIDTH = 5120;
const int FRAME_HEIGHT = 480;
const int MAX_NUM_OBJECTS=50;
//minimum and maximum object area
const int MIN_OBJECT_AREA = 10*10;
const int MAX_OBJECT_AREA = FRAME_HEIGHT*FRAME_WIDTH/1.5;
vector <Object> objects;
Mat temp;
threshold.copyTo(temp);
//these two vectors needed for output of findContours
vector< vector<Point> > contours;
vector<Vec4i> hierarchy;
//find contours of filtered image using openCV findContours function
findContours(temp,contours,hierarchy,CV_RETR_CCOMP,CV_CHAIN_APPROX_SIMPLE );
//use moments method to find our filtered object
double refArea = 0;
bool objectFound = false;
if (hierarchy.size() > 0) {
int numObjects = hierarchy.size();
//if number of objects greater than MAX_NUM_OBJECTS we have a noisy filter
if(numObjects<MAX_NUM_OBJECTS){
for (int index = 0; index >= 0; index = hierarchy[index][0]) {
Moments moment = moments((cv::Mat)contours[index]);
double area = moment.m00;
//if the area is less than 20 px by 20px then it is probably just noise
//if the area is the same as the 3/2 of the image size, probably just a bad filter
//we only want the object with the largest area so we safe a reference area each
//iteration and compare it to the area in the next iteration.
if(area>MIN_OBJECT_AREA){
Object object;
object.setXPos(moment.m10/area);
object.setYPos(moment.m01/area);
object.setType(theObject.getType());
object.setColor(theObject.getColor());
objects.push_back(object);
objectFound = true;
}else objectFound = false;
}
//let user know you found an object
if(objectFound ==true){
//draw object location on screen
drawObject(objects,cameraFeed,temp,contours,hierarchy);}
}else putText(cameraFeed,"TOO MUCH NOISE! ADJUST FILTER",Point(0,50),1,2,Scalar(0,0,255),2);
}
}
};
Main Code:
void Run()
{
int w, h;
_fps = 30;
IplImage *pCapImage[kameraSayisi];
IplImage *pDisplayImage;
PBYTE pCapBuffer = NULL;
// Create camera instance
for(int i = 0; i < kameraSayisi; i++)
{
_cam[i] = CLEyeCreateCamera(_cameraGUID[i], _mode, _resolution, _fps);
if(_cam[i] == NULL) return;
// Get camera frame dimensions
CLEyeCameraGetFrameDimensions(_cam[i], w, h);
// Create the OpenCV images
pCapImage[i] = cvCreateImage(cvSize(w, h), IPL_DEPTH_8U, 1);
// Set some camera parameters
CLEyeSetCameraParameter(_cam[i], CLEYE_GAIN, 0);
CLEyeSetCameraParameter(_cam[i], CLEYE_EXPOSURE, 511);
// Start capturing
CLEyeCameraStart(_cam[i]);
}
pDisplayImage = cvCreateImage(cvSize(w*kameraSayisi / 2, h * kameraSayisi/4 ), IPL_DEPTH_8U ,1);
if(_cam == NULL) return;
int iLastX = -1;
int iLastY = -1;
//Capture a temporary image from the camera
//program
bool trackObjects = true;
bool useMorphOps = true;
Mat HSV;
//Create a black image with the size as the camera output
Mat imgLines;
// imgLines = Mat::zeros( cvarrToMat(image).size(), CV_8UC3 );;
Mat threshold;
//x and y values for the location of the object
int x=0, y=0;
bool calibrationMode = false;
if(calibrationMode){
//create slider bars for HSV filtering
createTrackbars();
}
// image capturing loop
while(_running)
{
PBYTE pCapBuffer;
// Capture camera images
for(int i = 0; i < kameraSayisi; i++)
{
cvGetImageRawData(pCapImage[i], &pCapBuffer);
CLEyeCameraGetFrame(_cam[i], pCapBuffer, (i==0)?2000:0);
}
// Display stereo image
for(int i = 0; i < kameraSayisi; i++)
{
cvSetImageROI(pDisplayImage, cvRect(w * (i%4) ,i/4 * h, w, h));
cvCopy(pCapImage[i], pDisplayImage);
}
cvResetImageROI(pDisplayImage);
Mat imgOriginal;
Mat imgConverted = cvarrToMat(pDisplayImage);
if(calibrationMode==true)
{
//need to find the appropriate color range values
// calibrationMode must be false
//if in calibration mode, we track objects based on the HSV slider values.
//cvtColor(imgOriginal,imgOriginal,CV_BayerRG2RGB);
cvtColor(imgConverted,imgOriginal,CV_BayerGB2BGR);
cvtColor(imgOriginal,HSV,CV_BGR2HSV);
inRange(HSV,Scalar(H_MIN,S_MIN,V_MIN),Scalar(H_MAX,S_MAX,V_MAX),threshold);
morphOps(threshold);
imshow(_windowName + 'T',threshold);
//the folowing for canny edge detec
/// Create a matrix of the same type and size as src (for dst)
dst.create( imgOriginal.size(), src.type() );
/// Convert the image to grayscale
cvtColor( imgOriginal, src_gray, CV_BGR2GRAY );
/// Create a window
namedWindow( window_name, CV_WINDOW_AUTOSIZE );
/// Create a Trackbar for user to enter threshold
// createTrackbar( "Min Threshold:", window_name, &lowThreshold, max_lowThreshold, CannyThreshold );
/// Show the image
Object a = Object(H_MIN,S_MIN,V_MIN,H_MAX,S_MAX,V_MAX);
trackFilteredObject(a,threshold,HSV,imgOriginal);
}
else{
//we can use their member functions/information
Object blue("blue"), yellow("yellow"), red("red"), orange("orange"),white("white");
cvtColor(imgConverted,imgOriginal,CV_BayerGB2BGR);
//first find blue objects
cvtColor(imgOriginal,HSV,CV_RGB2HSV);
inRange(HSV,blue.getHSVmin(),blue.getHSVmax(),threshold);
morphOps(threshold);
//then yellows
inRange(HSV,yellow.getHSVmin(),yellow.getHSVmax(),threshold);
//then reds
inRange(HSV,red.getHSVmin(),red.getHSVmax(),threshold);
//then white
inRange(HSV,white.getHSVmin(),white.getHSVmax(),threshold);
//then orange
inRange(HSV,orange.getHSVmin(),orange.getHSVmax(),threshold);
trackFilteredObject(yellow,threshold,HSV,imgOriginal);
trackFilteredObject(white,threshold,HSV,imgOriginal);
trackFilteredObject(red,threshold,HSV,imgOriginal);
trackFilteredObject(blue,threshold,HSV,imgOriginal);
trackFilteredObject(orange,threshold,HSV,imgOriginal);
}
//delay 10ms so that screen can refresh.
//image will not appear without this waitKey() command
if (cvWaitKey(30) == 27) //wait for 'esc' key press for 30ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
// cvShowImage(_windowName, image);
imshow(_windowName,imgOriginal);
}
for(int i = 0; i < kameraSayisi; i++)
{
// Stop camera capture
CLEyeCameraStop(_cam[i]);
// Destroy camera object
CLEyeDestroyCamera(_cam[i]);
// Destroy the allocated OpenCV image
cvReleaseImage(&pCapImage[i]);
_cam[i] = NULL;
}
}

How can I remove unwanted part of an image with OpenCV using C++?

This is my input image:
and I would like to remove letterings from my image (Ex. DINING ROOM). How could I do this?
My code is below.
Mat skel;
Mat image=imread("InputImage4.jpg",1);
cvtColor(image,image,CV_BGR2GRAY);
threshold(image,image,50,255,THRESH_BINARY_INV);
WallFinder wall;
wall.setLineLengthAndGap(100,20);
wall.setMinVote(80);
skel=wall.skeleton(image);
Mat skeleton(Mat& img)
{
threshold(img, img, 50, 255, THRESH_BINARY);
Mat skel(img.size(), CV_8UC1, Scalar(0));
Mat temp;
Mat eroded;
Mat element = getStructuringElement(MORPH_CROSS, Size(3, 3));
bool done;
do
{
erode(img, eroded, element);
dilate(eroded, temp, element);
subtract(img, temp, temp);
bitwise_or(skel, temp, skel);
eroded.copyTo(img);
done = (countNonZero(img) == 0);
} while (!done);
dilate(skel,skel,Mat(),Point(-1,-1),2);
erode(skel,skel,Mat(),Point(-1,-1),2);
return skel;
}
And this my output image:
I must first remove letterings to do my job. (Like BATH)
Use the text-detection project described here to detect the area where text is present and then simply apply the color which has the maximum occurence in your image (i.e., the background) and voila.!
HTH
Here is a the code I made for cropping images, and made little modification to meet your requirement. And you need to manually select the area to remove.
#include <iostream>
#include "opencv2/opencv.hpp"
#include <stdio.h>
using namespace std;
using namespace cv;
Mat src,img,ROI;
Rect cropRect(0,0,0,0);
Point P1(0,0);
Point P2(0,0);
const char* winName="Crop Image";
bool clicked=false;
int i=0;
char imgName[15];
void checkBoundary(){
//check croping rectangle exceed image boundary
if(cropRect.width>img.cols-cropRect.x)
cropRect.width=img.cols-cropRect.x;
if(cropRect.height>img.rows-cropRect.y)
cropRect.height=img.rows-cropRect.y;
if(cropRect.x<0)
cropRect.x=0;
if(cropRect.y<0)
cropRect.height=0;
}
void showImage(){
img=src.clone();
checkBoundary();
rectangle(img, cropRect, Scalar(0,255,0), 1, 8, 0 );
imshow(winName,img);
}
void onMouse( int event, int x, int y, int f, void* ){
switch(event){
case CV_EVENT_LBUTTONDOWN :
clicked=true;
P1.x=x;
P1.y=y;
P2.x=x;
P2.y=y;
break;
case CV_EVENT_LBUTTONUP :
P2.x=x;
P2.y=y;
clicked=false;
break;
case CV_EVENT_MOUSEMOVE :
if(clicked){
P2.x=x;
P2.y=y;
}
break;
default : break;
}
if(clicked){
if(P1.x>P2.x){ cropRect.x=P2.x;
cropRect.width=P1.x-P2.x; }
else { cropRect.x=P1.x;
cropRect.width=P2.x-P1.x; }
if(P1.y>P2.y){ cropRect.y=P2.y;
cropRect.height=P1.y-P2.y; }
else { cropRect.y=P1.y;
cropRect.height=P2.y-P1.y; }
}
showImage();
}
int main()
{
cout<<"Click and drag for Selection"<<endl<<endl;
cout<<"------> Press 's' to save"<<endl<<endl;
cout<<"------> Press 'e' to reset"<<endl;
cout<<"------> Press 'r' to reset"<<endl<<endl;
cout<<"------> Press 'Esc' to quit"<<endl<<endl;
src=imread("img.jpg",1);
namedWindow(winName,WINDOW_NORMAL);
setMouseCallback(winName,onMouse,NULL );
imshow(winName,src);
while(1){
char c=waitKey();
if(c=='s'&&ROI.data){
sprintf(imgName,"%d.jpg",i++);
imwrite(imgName,img);
cout<<" Saved "<<imgName<<endl;
}
if(c=='e') {
if(cropRect.width>0&&cropRect.height>0){
ROI=src(cropRect);
ROI.setTo(Scalar(255,255,255));
showImage();
}
}
if(c==27) break;
if(c=='r') {cropRect.x=0;cropRect.y=0;cropRect.width=0;cropRect.height=0;}
showImage();
}
return 0;
}
Result:-

Need only one edge in Canny edge algorithm

When i use the canny edge algorithm, it produces the 2 edges opposite the thick colored line as expected, but i want only one edge to be displayed so as to make my line and curve detection algorithm much less complicated, any ideas on how i can make that happen ?
Here is the code :
bool CannyEdgeDetection(DataStructure& col)
{
Mat src, src_gray;
Mat dst, detected_edges, fin;
int WhiteCount = 0, BCount = 0;
char szFil1[32] = "ocv.bmp";
char szFil2[32] = "dst.bmp";
src = imread(szFil1);
dst = imread(szFil1);
blur( src_gray, detected_edges, Size(3,3) );
Canny( src, dst, 100, 200, 3 );
imwrite(szFil2, dst );
IplImage* img = cvLoadImage(szFil2);
int height = img->height;
int width = img->width;
int step = img->widthStep;
int channels = img->nChannels;
uchar * datau = (uchar *)img->imageData;
for(int i=0;i<height;i++){
for(int j=0;j<width;j++){
for(int k=0;k<channels;k++){
datau[i*step+j*channels+k] = 255 - datau[i*step+j*channels+k];
if (datau[i*step+j*channels+k]==0){
WhiteCount++;
col.pixel_col [i][j] = 2;
}
else{BCount++;
col.pixel_col[i][j] = 0;
}
}
}
}
cvSaveImage("img.bmp" ,img);
return 0;
}
This is not the original image but similar :
Which part do i comment out to be able to read black images in white backgrounds ? or any colored image ?
bool done;
do
{
cv::morphologyEx(img, temp, cv::MORPH_OPEN, element);
cv::bitwise_not(temp, temp);
cv::bitwise_and(img, temp, temp);
cv::bitwise_or(skel, temp, skel);
cv::erode(img, img, element);
double max;
cv::minMaxLoc(img, 0, &max);
done = (max == 0);
} while (!done);
That process is called skeletonization or thinning. You can google for that.
Here is a simple method for skeletonization : skeletonization OpenCV In C#
Below is the output I got when applied above method to your image ( Image is inverted before skeletonization because above method work for white images in black background, just opposite case of your input image).