Skip to content

Commit

Permalink
added comments for all files
Browse files Browse the repository at this point in the history
  • Loading branch information
internaut committed Jun 18, 2014
1 parent 4f4ead1 commit a250dc9
Show file tree
Hide file tree
Showing 14 changed files with 421 additions and 26 deletions.
51 changes: 47 additions & 4 deletions detect.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Detection core implementation file.
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* This file contains code and inspiration from ArUco library developed at the
* Ava group of the Univeristy of Cordoba (Spain).
* See http://sourceforge.net/projects/aruco/
*
* See LICENSE for license.
*/

#include "detect.h"

#include "tools.h"
Expand All @@ -8,10 +23,12 @@ using namespace ocv_ar;
#pragma mark public methods

Detect::Detect(IdentificatorType identType, float markerSizeM, FlipMode flip) {
// use marker size default
if (markerSizeM <= 0.0f) markerSizeM = OCV_AR_CONF_DEFAULT_MARKER_SIZE_REAL;

printf("ocv_ar::Detect - projection flip mode: %d\n", (int)flip);

// set defaults
markerScale = markerSizeM;
flipProj = flip;
prepared = false;
Expand All @@ -30,6 +47,8 @@ Detect::Detect(IdentificatorType identType, float markerSizeM, FlipMode flip) {
downsampleSizeW = downsampleSizeH = 0;

ident = NULL;

// set identificator
setIdentificatorType(identType);

#if !defined(OCV_AR_CONF_DOWNSAMPLE) && defined(OCV_AR_CONF_RESIZE_W) && defined(OCV_AR_CONF_RESIZE_H)
Expand All @@ -39,6 +58,8 @@ Detect::Detect(IdentificatorType identType, float markerSizeM, FlipMode flip) {
}

Detect::~Detect() {
// delete allocated memory

if (inFrameOrigGray) delete inFrameOrigGray;
if (inFrame) delete inFrame;
if (procFrame) delete procFrame;
Expand All @@ -51,6 +72,7 @@ void Detect::setIdentificatorType(IdentificatorType identType) {

printf("ocv_ar::Detect - loading identificator type %d\n", identType);

// create an identificator object
switch (identType) {
case IDENT_TYPE_CODE_7BIT:
ident = new Identificator7BitCode();
Expand All @@ -67,6 +89,7 @@ void Detect::setIdentificatorType(IdentificatorType identType) {
break;
}

// set normalized marker coordinates for 2D and 3D space
normMarkerCoord2D.clear();
normMarkerCoord3D.clear();

Expand Down Expand Up @@ -150,6 +173,7 @@ void Detect::setCamIntrinsics(const cv::Mat &cam, const cv::Mat &dist) {
float *Detect::getProjMat(float viewW, float viewH) {
assert(!camMat.empty() && viewW > 0.0f && viewH > 0.0f && prepared);

// re-calculate the projection matrix if necessary
if (viewW != projMatUsedSize.width || viewH != projMatUsedSize.height) {
calcProjMat(viewW, viewH);
}
Expand All @@ -175,6 +199,7 @@ void Detect::setFrameOutputLevel(FrameProcLevel level) {
delete outFrame;
}

// allocate memory for the output frame
outFrame = new cv::Mat(outH, outW, CV_8UC1);

printf("ocv_ar::Detect - set output frame level: %d (output frame size %dx%d)", level, outW, outH);
Expand All @@ -189,6 +214,8 @@ void Detect::setInputFrame(cv::Mat *frame) {
}

void Detect::processFrame() {
// defines the whole marker detection pipeline:

preprocess();
performThreshold();
findContours();
Expand All @@ -206,6 +233,8 @@ cv::Mat *Detect::getOutputFrame() const {
#pragma mark private methods

void Detect::preprocess() {
// downscale the image

#ifdef OCV_AR_CONF_DOWNSAMPLE
for (int i = 0; i < OCV_AR_CONF_DOWNSAMPLE; i++) {
cv::pyrDown(*inFrameOrigGray, *inFrame);
Expand All @@ -222,6 +251,8 @@ void Detect::preprocess() {
}

void Detect::performThreshold() {
// perform thresholding

cv::adaptiveThreshold(*inFrame,
*procFrame,
255,
Expand Down Expand Up @@ -249,6 +280,7 @@ void Detect::findContours() {
it != allContours.end();
++it)
{
// add this contour to our <curContour> vector in case it could form a marker
if (it->size() >= OCV_AR_CONF_MIN_CONTOUR_PTS) {
curContours.push_back(*it);
}
Expand All @@ -265,10 +297,12 @@ void Detect::findContours() {
void Detect::findMarkerCandidates() {
const float minContourLengthAllowed = OCV_AR_CONF_MIN_CONTOUR_LENGTH * OCV_AR_CONF_MIN_CONTOUR_LENGTH;

// tabula rasa for the new frame
foundMarkers.clear();
possibleMarkers.clear();
PointVec approxCurve;

// analyze each contour
for (ContourVec::const_iterator it = curContours.begin();
it != curContours.end();
++it)
Expand Down Expand Up @@ -302,6 +336,8 @@ void Detect::findMarkerCandidates() {

// printf("ocv_ar::Detect - Num. marker candidates: %lu\n", possibleMarkers.size());

// duplicate markers are possible, especially when double edges are detected
// filter them out
discardDuplicateMarkers(possibleMarkers);

// printf("ocv_ar::Detect - Num. marker candidates without duplicates: %lu\n", possibleMarkers.size());
Expand Down Expand Up @@ -376,16 +412,23 @@ void Detect::identifyMarkers() {
}

void Detect::estimatePositions() {
for (vector<Marker *>::iterator it = foundMarkers.begin(); it != foundMarkers.end(); ++it) {
// estimate the 3D pose of each found marker
for (vector<Marker *>::iterator it = foundMarkers.begin();
it != foundMarkers.end();
++it)
{
Marker *marker = *it;

cv::Mat rVec;
cv::Mat tVec;
// find marker pose from 3D-2D point correspondences between <normMarkerCoord3D>
// and 2D points in <marker->getPoints()>
cv::Mat rVec; // pose rotation vector
cv::Mat tVec; // pose translation vector
cv::solvePnP(normMarkerCoord3D, marker->getPoints(),
camMat, distCoeff,
rVec, tVec,
false);

// generate an OpenGL model-view matrix from the rotation and translation vectors
marker->updatePoseMat(rVec, tVec);
}
}
Expand Down Expand Up @@ -554,6 +597,6 @@ void Detect::calcProjMat(float viewW, float viewH) {
projMat[8] = -projMat[8];
projMat[12] = -projMat[12];
}


/* END modified code from ArUco lib */
}
4 changes: 4 additions & 0 deletions detect.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* This file contains code and inspiration from ArUco library developed at the
* Ava group of the Univeristy of Cordoba (Spain).
* See http://sourceforge.net/projects/aruco/
*
* See LICENSE for license.
*/

Expand Down
11 changes: 11 additions & 0 deletions ident.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Marker identification base class -- implementation file.
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* See LICENSE for license.
*/

#include "ident.h"

using namespace ocv_ar;
Expand Down
42 changes: 39 additions & 3 deletions ident.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,14 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Marker identification base class -- header file.
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* See LICENSE for license.
*/

#ifndef OCV_AR_IDENT_H
#define OCV_AR_IDENT_H

Expand All @@ -8,26 +19,51 @@

namespace ocv_ar {

/**
* Abstract base class for all identificators providing common methods and a uniform
* interface.
*/
class IdentificatorBase {
public:
/**
* Base constructor to set the identificator type <t> and the required marker size
* <markerSize> in pixels.
*/
IdentificatorBase(IdentificatorType t, int markerSize) : reqMarkerSize(markerSize),
type(t)
{};

/**
* Empty virtual deconstructor.
*/
virtual ~IdentificatorBase() {};

/**
* Abstract method to read a marker code from the image region <area> and save
* possible results in <marker>.
* Returns true if the code could be read, otherwise false.
*/
virtual bool readMarkerCode(const cv::Mat &area, Marker &marker) = 0;

virtual int getRequiredMarkerSize() const { return reqMarkerSize; }
/**
* Returns the required marker size.
*/
int getRequiredMarkerSize() const { return reqMarkerSize; }

/**
* Returns the idenficator type.
*/
IdentificatorType getType() { return type; }

protected:
/**
* Helper function to set an <id> and a valid rotation <rot> to a <marker>.
*/
void setFoundPropertiesForMarker(Marker &marker, int id, int rot);


IdentificatorType type;
int reqMarkerSize;
IdentificatorType type; // identificator type
int reqMarkerSize; // required marker size
};

}
Expand Down
15 changes: 15 additions & 0 deletions ident_7bit.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,18 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Marker identification for ArUco style 7x7 markers -- implementation file.
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* This file contains code and inspiration from ArUco library developed at the
* Ava group of the Univeristy of Cordoba (Spain).
* See http://sourceforge.net/projects/aruco/
*
* See LICENSE for license.
*/

#include "ident_7bit.h"

using namespace ocv_ar;
Expand Down
43 changes: 41 additions & 2 deletions ident_7bit.h
Original file line number Diff line number Diff line change
@@ -1,3 +1,20 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Marker identification for ArUco style 7x7 markers -- header file.
* Note: Although the markers use 7x7 binary fields, only the inner 5x5 fields
* carry information (i.e. the marker code).
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* This file contains code and inspiration from ArUco library developed at the
* Ava group of the Univeristy of Cordoba (Spain).
* See http://sourceforge.net/projects/aruco/
*
* See LICENSE for license.
*/

#ifndef OCV_AR_IDENT_7BIT_H
#define OCV_AR_IDENT_7BIT_H

Expand All @@ -9,22 +26,44 @@

namespace ocv_ar {

/**
* Marker idenfication for ArUco style 7x7 markers.
* A possible marker square can be analyzed and - if it is a valid marker - its ID
* can be calculated from the code embedded in the inner 5x5 binary marker fields.
*/
class Identificator7BitCode : public IdentificatorBase {
public:
/**
* Constructor. Create a new idenficiator of type IDENT_TYPE_CODE_7BIT.
*/
Identificator7BitCode() : IdentificatorBase(IDENT_TYPE_CODE_7BIT, 7 * OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD),
markerCellSize(OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD),
minSetMarkerPixels(OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD * OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD / 2)
{};

/**
* Try to read the marker code from the quadratic image part <area> by trying out all
* four possbile rotations of the image. If an ID could be read, set the found ID and
* valid rotation in <marker> and return true, otherwise return false.
*/
virtual bool readMarkerCode(const cv::Mat &area, Marker &marker);

private:
/**
* Helper function to check if a marker code is valid when the extracted marker code
* matrix <m> is read in direction <dir>.
*/
bool checkMarkerCode(const cv::Mat &m, int dir) const;

/**
* Helper function to read the marker code from the extracted marker code
* matrix <m> by using direction <dir>.
*/
int markerCodeToId(const cv::Mat &m, int dir) const;


int markerCellSize;
int minSetMarkerPixels;
int markerCellSize; // cell size of each marker field in pixels
int minSetMarkerPixels; // minimum of white marker pixels that must be set if a field should be regarded "1"
};

}
Expand Down
19 changes: 18 additions & 1 deletion ident_templ.cpp
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
/**
* ocv_ar - OpenCV based Augmented Reality library
*
* Marker identification via simple template matching of binary
* images -- implementation file.
*
* Author: Markus Konrad <konrad@htw-berlin.de>, June 2014.
* INKA Research Group, HTW Berlin - http://inka.htw-berlin.de/
*
* See LICENSE for license.
*/

#include "ident_templ.h"

#include "tools.h"
Expand All @@ -11,9 +23,12 @@ IdentificatorTemplMatch::IdentificatorTemplMatch() :
borderSize(OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD),
minSetMarkerPixels(OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD * OCV_AR_CONF_MARKER_CODE_PX_PER_FIELD / 2)
{
// calculate defaults
templSize = reqMarkerSize - 2 * borderSize;
templSizeSq = templSize * templSize;
printf("ocv_ar::IdentificatorTemplMatch - req. marker size: %d, templ. size: %d\n", reqMarkerSize, templSize);

printf("ocv_ar::IdentificatorTemplMatch - req. marker size: %d, templ. size: %d\n",
reqMarkerSize, templSize);
}

IdentificatorTemplMatch::~IdentificatorTemplMatch() {
Expand Down Expand Up @@ -147,8 +162,10 @@ bool IdentificatorTemplMatch::checkTemplateRotations(const cv::Mat &marker, cons
cv::Mat errorMat(marker.rows, marker.cols, CV_8UC1);

for (int r = 0; r < 4; r++) { // check all four rotations
// do a bitwise or so that we get "1"s where the two images do not fit
cv::bitwise_xor(marker, templRotations[r], errorMat);

// could the pixels that do not fit
float errRate = (float)cv::countNonZero(errorMat) / (float)templSizeSq;

printf("ocv_ar::IdentificatorTemplMatch - rotation %d, error rate %f\n", r, errRate);
Expand Down
Loading

0 comments on commit a250dc9

Please sign in to comment.