Added the camera calibration pattern detection.

This commit is contained in:
2014-04-09 14:56:00 -04:30
parent 5c92d603d2
commit 453c3a36e5
5 changed files with 304 additions and 322 deletions

View File

@@ -22,6 +22,7 @@
//#define CAN_LOG //#define CAN_LOG
extern "C"{ extern "C"{
#ifdef CAN_LOG #ifdef CAN_LOG
#define log(TAG, MSG) (__android_log_write(ANDROID_LOG_DEBUG, TAG, MSG)) #define log(TAG, MSG) (__android_log_write(ANDROID_LOG_DEBUG, TAG, MSG))
const char * TAG = "CVPROC_NATIVE"; const char * TAG = "CVPROC_NATIVE";
@@ -63,4 +64,23 @@ const char * TAG = "CVPROC_NATIVE";
env->ReleaseIntArrayElements(codes, _codes, 0); env->ReleaseIntArrayElements(codes, _codes, 0);
} }
JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_findCalibrationPattern(
JNIEnv* env,
jobject jobj,
jlong addrMatIn,
jlong addrMatOut
){
log(TAG, "Requesting native data.");
cv::Mat& myuv = *(cv::Mat*)addrMatIn;
cv::Mat& mbgr = *(cv::Mat*)addrMatOut;
log(TAG, "Converting color space before processing.");
cv::cvtColor(myuv, mbgr, CV_RGB2BGR);
log(TAG, "Finding markers.");
nxtar::calibrateCamera(mbgr);
}
} }

View File

@@ -24,86 +24,33 @@
namespace nxtar{ namespace nxtar{
static int PATTERN_DETECTION_PARAMS = cv::CALIB_CB_ADAPTIVE_THRESH + cv::CALIB_CB_NORMALIZE_IMAGE + cv::CALIB_CB_FAST_CHECK;
static const cv::TermCriteria termCriteria = cv::TermCriteria(CV_TERMCRIT_EPS + CV_TERMCRIT_ITER, 30, 0.1);
static const cv::Scalar COLOR = cv::Scalar(255, 255, 255); static const cv::Scalar COLOR = cv::Scalar(255, 255, 255);
static const cv::Size checkersPatternSize(6, 9);
class Marker;
typedef std::vector<std::vector<cv::Point> > contours_vector;
typedef std::vector<cv::Point2f> points_vector;
typedef std::vector<Marker> markers_vector;
class Marker{
public:
~Marker();
points_vector points;
int code;
};
float perimeter (points_vector &); float perimeter (points_vector &);
int hammDistMarker (cv::Mat); int hammDistMarker (cv::Mat);
cv::Mat rotate (cv::Mat); cv::Mat rotate (cv::Mat);
void binarize(cv::Mat &, cv::Mat &);
void findContours(cv::Mat &, contours_vector &, int);
void renderContours(contours_vector &, cv::Mat &);
void renderMarkers(markers_vector &, cv::Mat &);
void warpMarker(Marker &, cv::Mat &, cv::Mat &);
int decodeMarker (cv::Mat &); int decodeMarker (cv::Mat &);
void fixCorners(cv::Mat &, Marker &); void renderMarkers (markers_vector &, cv::Mat &);
void isolateMarkers (const contours_vector &, markers_vector &); void isolateMarkers (const contours_vector &, markers_vector &);
void findContours (cv::Mat &, contours_vector &, int);
void warpMarker (Marker &, cv::Mat &, cv::Mat &);
void getAllMarkers(std::vector<int> & codes, cv::Mat & img){ void getAllMarkers(std::vector<int> & codes, cv::Mat & img){
cv::Mat gray, thresh, cont, mark; cv::Mat gray, thresh, cont, mark;
contours_vector contours; contours_vector contours;
markers_vector markers; markers_vector markers;
markers_vector valid_markers; markers_vector valid_markers;
codes.clear();
cv::cvtColor(img, gray, CV_BGR2GRAY);
binarize(gray, thresh);
findContours(thresh, contours, 40);
isolateMarkers(contours, markers);
for(int i = 0; i < markers.size(); i++){
warpMarker(markers[i], gray, mark);
int code = decodeMarker(mark);
if(code != -1){
markers[i].code = code;
valid_markers.push_back(markers[i]);
}
}
for(int i = 0; i < valid_markers.size(); i++)
fixCorners(gray, valid_markers[i]);
cont = cv::Mat::zeros(img.size(), CV_8UC3);
renderMarkers(valid_markers, cont);
img = img + cont;
for(int i = 0; i < valid_markers.size(); i++){
codes.push_back(valid_markers[i].code);
}
markers.clear();
contours.clear();
valid_markers.clear();
}
#ifdef DESKTOP #ifdef DESKTOP
void getAllMarkers_d(std::vector<int> & codes, cv::Mat & img){
cv::Mat gray, thresh, cont, mark;
contours_vector contours;
markers_vector markers;
markers_vector valid_markers;
std::ostringstream oss; std::ostringstream oss;
#endif
codes.clear(); codes.clear();
cv::cvtColor(img, gray, CV_BGR2GRAY); cv::cvtColor(img, gray, CV_BGR2GRAY);
binarize(gray, thresh); cv::adaptiveThreshold(gray, thresh, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 7, 7);
findContours(thresh, contours, 40); findContours(thresh, contours, 40);
isolateMarkers(contours, markers); isolateMarkers(contours, markers);
@@ -118,15 +65,8 @@ namespace nxtar{
} }
} }
for(int i = 0; i < valid_markers.size(); i++)
fixCorners(gray, valid_markers[i]);
cont = cv::Mat::zeros(img.size(), CV_8UC3);
renderMarkers(valid_markers, cont);
img = img + cont;
for(int i = 0; i < valid_markers.size(); i++){ for(int i = 0; i < valid_markers.size(); i++){
#ifdef DESKTOP
oss << valid_markers[i].code; oss << valid_markers[i].code;
cv::putText(mark, oss.str(), cv::Point(5, 250), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(128), 3, 8); cv::putText(mark, oss.str(), cv::Point(5, 250), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(128), 3, 8);
@@ -140,18 +80,33 @@ namespace nxtar{
oss.str(""); oss.str("");
oss.clear(); oss.clear();
#endif
cv::cornerSubPix(gray, valid_markers[i].points, cvSize(10, 10), cvSize(-1, -1), termCriteria);
codes.push_back(valid_markers[i].code); codes.push_back(valid_markers[i].code);
} }
cont = cv::Mat::zeros(img.size(), CV_8UC3);
renderMarkers(valid_markers, cont);
img = img + cont;
markers.clear(); markers.clear();
contours.clear(); contours.clear();
valid_markers.clear(); valid_markers.clear();
} }
#endif
void binarize(cv::Mat & src, cv::Mat & dst){ void calibrateCamera(cv::Mat & img){
cv::adaptiveThreshold(src, dst, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 7, 7); bool patternfound;
points_vector corners;
cv::Mat gray;
cv::cvtColor(img, gray, CV_BGR2GRAY);
patternfound = cv::findChessboardCorners(gray, checkersPatternSize, corners, PATTERN_DETECTION_PARAMS);
if(patternfound)
cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1), termCriteria);
cv::drawChessboardCorners(img, checkersPatternSize, cv::Mat(corners), patternfound);
} }
void findContours(cv::Mat & img, contours_vector & v, int minP){ void findContours(cv::Mat & img, contours_vector & v, int minP){
@@ -166,10 +121,6 @@ namespace nxtar{
} }
} }
void renderContours(contours_vector & v, cv::Mat & dst){
cv::drawContours(dst, v, -1, COLOR, 1, CV_AA);
}
void renderMarkers(markers_vector & v, cv::Mat & dst){ void renderMarkers(markers_vector & v, cv::Mat & dst){
contours_vector cv; contours_vector cv;
@@ -300,6 +251,7 @@ namespace nxtar{
return dist; return dist;
} }
cv::Mat rotate(cv::Mat in){ cv::Mat rotate(cv::Mat in){
cv::Mat out; cv::Mat out;
in.copyTo(out); in.copyTo(out);
@@ -375,10 +327,6 @@ namespace nxtar{
return -1; return -1;
} }
void fixCorners(cv::Mat & img, Marker & m){
cv::cornerSubPix(img, m.points, cvSize(10, 10), cvSize(-1, -1), cvTermCriteria(CV_TERMCRIT_ITER, 30, 0.1));
}
float perimeter(points_vector & p){ float perimeter(points_vector & p){
float per = 0.0f, dx, dy; float per = 0.0f, dx, dy;

View File

@@ -20,10 +20,22 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
namespace nxtar{ namespace nxtar{
class Marker;
typedef std::vector<std::vector<cv::Point> > contours_vector;
typedef std::vector<cv::Point2f> points_vector;
typedef std::vector<Marker> markers_vector;
class Marker{
public:
~Marker();
points_vector points;
int code;
};
void getAllMarkers(std::vector<int> &, cv::Mat &); void getAllMarkers(std::vector<int> &, cv::Mat &);
#ifdef DESKTOP void calibrateCamera(cv::Mat &);
void getAllMarkers_d(std::vector<int> &, cv::Mat &);
#endif
} }
#endif #endif

View File

@@ -9,4 +9,4 @@
# Project target. # Project target.
target=android-19 target=android-19
android.library.reference.1=../../../../../Escritorio/OpenCV-2.4.7-android-sdk/sdk/java android.library.reference.1=../../../../../NVPACK/OpenCV-2.4.5-Tegra-sdk-r2/sdk/java

View File

@@ -57,17 +57,18 @@ public class MainActivity extends AndroidApplication implements Toaster, Multica
static{ static{
if(!OpenCVLoader.initDebug()){ if(!OpenCVLoader.initDebug()){
Gdx.app.exit(); System.exit(1);
} }
try{ try{
System.loadLibrary("cvproc"); System.loadLibrary("cvproc");
ocvOn = true; ocvOn = true;
}catch(UnsatisfiedLinkError u){ }catch(UnsatisfiedLinkError u){
Gdx.app.exit(); System.exit(1);
} }
} }
public native void getMarkerCodesAndLocations(long inMat, long outMat, int[] codes); public native void getMarkerCodesAndLocations(long inMat, long outMat, int[] codes);
public native void findCalibrationPattern(long inMat, long outMat);
@Override @Override
public void onCreate(Bundle savedInstanceState){ public void onCreate(Bundle savedInstanceState){
@@ -167,7 +168,8 @@ public class MainActivity extends AndroidApplication implements Toaster, Multica
Mat outImg = new Mat(); Mat outImg = new Mat();
Utils.bitmapToMat(tFrame, inImg); Utils.bitmapToMat(tFrame, inImg);
getMarkerCodesAndLocations(inImg.getNativeObjAddr(), outImg.getNativeObjAddr(), codes); //getMarkerCodesAndLocations(inImg.getNativeObjAddr(), outImg.getNativeObjAddr(), codes);
findCalibrationPattern(inImg.getNativeObjAddr(), outImg.getNativeObjAddr());
Mat temp = new Mat(); Mat temp = new Mat();
Imgproc.cvtColor(outImg, temp, Imgproc.COLOR_BGR2RGB); Imgproc.cvtColor(outImg, temp, Imgproc.COLOR_BGR2RGB);