image.cpp
Go to the documentation of this file.
/*
* Copyright (C) 2018 dimercur
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "image.h"
#include <iostream>
using namespace cv;
#ifndef __STUB__
#ifdef __FOR_PC__
VideoCapture cap;
#else
using namespace raspicam;
#endif /* __FOR_PC__ */
#else
Image stubImg;
#endif
using namespace std;
float calculAngle(Position * positionRobot);
int cropArena(Image *imgInput, Image *imgOutput, Arene *AreneInput);
float euclideanDist(Point& p, Point& q);
void draw_arena(Image *imgInput, Image *imgOutput, Arene *monArene)
{
if(imgInput!=imgOutput)
*imgOutput=imgInput->clone();
rectangle(*imgOutput,monArene->tl(),monArene->br(),Scalar(0,0,125),2,8,0);
}
int open_camera(Camera *camera)
{
#ifndef __STUB__
#ifdef __FOR_PC__
// open the default camera, use something different from 0 otherwise;
// Check VideoCapture documentation.
printf("Opening Camera...\n");
if(!cap.open(0))
return -1;
return 0;
#else // for raspberry
camera->set(CV_CAP_PROP_FORMAT, CV_8UC3);
camera->set(CV_CAP_PROP_FRAME_WIDTH,WIDTH);
camera->set(CV_CAP_PROP_FRAME_HEIGHT,HEIGHT);
printf("Opening Camera...\n");
if (!(camera->open())) {
perror("Can't open Camera\n") ;
return -1;
}
else
{
printf("Camera warmup 2sec\n");
sleep(2);
printf("Start capture\n");
return 0;
}
#endif /* __FOR_PC__ */
#else
return 0;
#endif
}
void get_image(Camera *camera, Image * monImage, const char * fichier) // getImg(Camera, Image img);
{
#ifndef __STUB__
#ifdef __FOR_PC__
if (monImage != NULL)
{
cap>>*monImage;
}
#else // for raspberry
camera->grab();
camera->retrieve(*monImage);
cvtColor(*monImage,*monImage,CV_BGR2RGB);
#endif /* __FOR_PC__ */
#else
stubImg = imread(fichier, CV_LOAD_IMAGE_COLOR);
stubImg.copyTo(*monImage);
#endif
}
void close_camera(Camera *camera) // closeCam(Camera) : camera Entrer
{
#ifndef __STUB__
#ifdef __FOR_PC__
cap.release();
#else // for raspberry
camera->release();
#endif /* __FOR_PC__ */
#else
#endif
}
int detect_arena(Image *monImage, Arene *rectangle) // Image en entrée // rectangle en sortie
{
vector<vector<Point> > contours;
vector<Point> approx;
vector<Vec4i> hierarchy;
Image imageTrt;
cvtColor(*monImage,imageTrt,CV_RGB2GRAY); // conversion en niveau de gris
threshold(imageTrt,imageTrt,128,255,CV_THRESH_BINARY); // Threshold les éléments les plus clair
Canny(imageTrt, imageTrt, 100,200,3); // detection d'angle
findContours(imageTrt, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
for(unsigned int i = 0; i < contours.size();i++)
{
approxPolyDP(Image(contours[i]), approx, arcLength(Image(contours[i]), true)*0.1, true);
if(approx.size()==4 && fabs(cv::contourArea(contours[i])) > 100000)
{
*rectangle = boundingRect(Image(contours[i]));
return 0;
}
}
return -1;
}
int cropArena(Image *imgInput, Image *imgOutput, Arene *areneInput) // image // rectangle // image2
{
Image img;
img=imgInput->clone();
*imgOutput = img(*areneInput);
return 0;
}
float euclideanDist(Point& p, Point& q) {
Point diff = p - q;
return cv::sqrt(diff.x*diff.x + diff.y*diff.y);
}
void compress_image(Image *imgInput, Jpg *imageCompress) // image entrée // imageEncodé en sortie
{
imencode(".jpg",*imgInput,*imageCompress);
}
int detect_position(Image *imgInput, Position *posTriangle, Arene * monArene) // entree : image / sortie tab pos
{
vector<vector<Point> > contours;
vector<Point> approx;
vector<Vec4i> hierarchy;
Image imgTraitment;
if(monArene==NULL)
imgTraitment=imgInput->clone();
else
cropArena(imgInput,&imgTraitment, monArene);
cvtColor(imgTraitment,imgTraitment,CV_RGB2GRAY);
threshold(imgTraitment,imgTraitment,128,255,CV_THRESH_BINARY);
findContours(imgTraitment, contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, Point(0, 0));
int nbrTriangle = 0;
for(unsigned int i = 0;i < contours.size();i++)
{
approxPolyDP(Mat(contours[i]), approx, arcLength(Mat(contours[i]), true)*0.17, true);
if(approx.size() == 3 && fabs(contourArea(contours[i])) > 200 && fabs(contourArea(contours[i])) < 700)
{
Point a,b,c;
Point center;
a = approx[0];
b = approx[1];
c = approx[2];
if(monArene !=NULL) // ajout de l'offset de l'arène
{
a.x += monArene->x;
a.y += monArene->y;
b.x += monArene->x;
b.y += monArene->y;
c.x += monArene->x;
c.y += monArene->y;
}
center.x = (a.x + b.x + c.x)/3;
center.y = (a.y + b.y + c.y)/3;
posTriangle[nbrTriangle].center=center;
if(euclideanDist(center,b) > euclideanDist(center,a) && euclideanDist(center,b) > euclideanDist(center,c) )
{
posTriangle[nbrTriangle].direction=b;
//line(img,center,b,Scalar(0,125,0),2,8,0);
}
else if(euclideanDist(center,a) > euclideanDist(center,c))
{
posTriangle[nbrTriangle].direction=a;
//line(img,center,a,Scalar(0,125,0),2,8,0);
}
else
{
posTriangle[nbrTriangle].direction=c;
//line(img,center,c,Scalar(0,125,0),2,8,0);
}
posTriangle[nbrTriangle].angle=calculAngle(&posTriangle[nbrTriangle]);
nbrTriangle++;
}
}
return nbrTriangle;
}
void draw_position(Image *imgInput, Image *imgOutput, Position *positionRobot) // img E/S pos : E
{
if(imgInput!=imgOutput)
{
*imgOutput=imgInput->clone();
}
line(*imgOutput,positionRobot->center,positionRobot->direction,Scalar(0,125,0),2,8,0);
}
float calculAngle(Position * positionRobot) // position en entree
{
float a = positionRobot->direction.x - positionRobot->center.x;
float b = positionRobot->direction.y - positionRobot->center.y ;
float angle = atan2(b,a);
return angle * 180.f/M_PI;
}
compress_image
void compress_image(Image *imgInput, Jpg *imageCompress)
Détecte la position d&#39;un robot.
Definition: image.cpp:164
get_image
void get_image(Camera *camera, Image *monImage, const char *fichier)
Capture une image avec la camera passée en entrée. En cas de test sans camera, la fonction charge une...
Definition: image.cpp:93
Position::center
Point center
Definition: image.h:70
Position::angle
float angle
Definition: image.h:72
WIDTH
#define WIDTH
Definition: image.h:44
close_camera
void close_camera(Camera *camera)
Ferme la camera passé en paramètre.
Definition: image.cpp:112
cropArena
int cropArena(Image *imgInput, Image *imgOutput, Arene *AreneInput)
Definition: image.cpp:150
Arene
Rect Arene
Definition: image.h:66
std
Image
Mat Image
Definition: image.h:55
cv
detect_arena
int detect_arena(Image *monImage, Arene *rectangle)
Détecte une arène dans une image fournis en paramètre.
Definition: image.cpp:126
open_camera
int open_camera(Camera *camera)
Ouvre une camera.
Definition: image.cpp:58
image.h
Functions for image treatment.
Position
Definition: image.h:69
detect_position
int detect_position(Image *imgInput, Position *posTriangle, Arene *monArene)
Détecte la position d&#39;un robot.
Definition: image.cpp:170
draw_arena
void draw_arena(Image *imgInput, Image *imgOutput, Arene *monArene)
Dessine le plus petit rectangle contenant l&#39;arène.
Definition: image.cpp:51
euclideanDist
float euclideanDist(Point &p, Point &q)
Definition: image.cpp:159
Jpg
vector< unsigned char > Jpg
Definition: image.h:67
Camera
RaspiCam_Cv Camera
Definition: image.h:58
raspicam
calculAngle
float calculAngle(Position *positionRobot)
Definition: image.cpp:253
HEIGHT
#define HEIGHT
Definition: image.h:45
draw_position
void draw_position(Image *imgInput, Image *imgOutput, Position *positionRobot)
Dessine sur une image en entrée la position d&#39;un robot et sa direction.
Definition: image.cpp:244
Position::direction
Point direction
Definition: image.h:71