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";
@@ -29,38 +30,57 @@ const char * TAG = "CVPROC_NATIVE";
#define log(TAG, MSG) (1 + 1) #define log(TAG, MSG) (1 + 1)
#endif #endif
JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_getMarkerCodesAndLocations( JNIEXPORT void JNICALL Java_ve_ucv_ciens_ccg_nxtar_MainActivity_getMarkerCodesAndLocations(
JNIEnv* env, JNIEnv* env,
jobject jobj, jobject jobj,
jlong addrMatIn, jlong addrMatIn,
jlong addrMatOut, jlong addrMatOut,
jintArray codes jintArray codes
){ ){
char codeMsg[128]; char codeMsg[128];
std::vector<int> vCodes; std::vector<int> vCodes;
log(TAG, "Requesting native data."); log(TAG, "Requesting native data.");
cv::Mat& myuv = *(cv::Mat*)addrMatIn; cv::Mat& myuv = *(cv::Mat*)addrMatIn;
cv::Mat& mbgr = *(cv::Mat*)addrMatOut; cv::Mat& mbgr = *(cv::Mat*)addrMatOut;
jint * _codes = env->GetIntArrayElements(codes, 0); jint * _codes = env->GetIntArrayElements(codes, 0);
log(TAG, "Converting color space before processing."); log(TAG, "Converting color space before processing.");
cv::cvtColor(myuv, mbgr, CV_RGB2BGR); cv::cvtColor(myuv, mbgr, CV_RGB2BGR);
log(TAG, "Finding markers."); log(TAG, "Finding markers.");
nxtar::getAllMarkers(vCodes, mbgr); nxtar::getAllMarkers(vCodes, mbgr);
log(TAG, "Copying marker codes."); log(TAG, "Copying marker codes.");
for(int i = 0; i < vCodes.size() && i < 15; i++){ for(int i = 0; i < vCodes.size() && i < 15; i++){
_codes[i] = vCodes[i]; _codes[i] = vCodes[i];
sprintf(codeMsg, "Code [%d] = %d", i, vCodes[i]); sprintf(codeMsg, "Code [%d] = %d", i, vCodes[i]);
log(TAG, codeMsg); log(TAG, codeMsg);
}
vCodes.clear();
log(TAG, "Releasing native data.");
env->ReleaseIntArrayElements(codes, _codes, 0);
} }
vCodes.clear();
log(TAG, "Releasing native data.");
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,375 +24,323 @@
namespace nxtar{ namespace nxtar{
static const cv::Scalar COLOR = cv::Scalar(255, 255, 255); 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::Size checkersPatternSize(6, 9);
float perimeter (points_vector &);
int hammDistMarker (cv::Mat);
cv::Mat rotate (cv::Mat);
int decodeMarker (cv::Mat &);
void renderMarkers (markers_vector &, cv::Mat &);
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){
cv::Mat gray, thresh, cont, mark;
contours_vector contours;
markers_vector markers;
markers_vector valid_markers;
#ifdef DESKTOP
std::ostringstream oss;
#endif
class Marker; codes.clear();
typedef std::vector<std::vector<cv::Point> > contours_vector; cv::cvtColor(img, gray, CV_BGR2GRAY);
typedef std::vector<cv::Point2f> points_vector; cv::adaptiveThreshold(gray, thresh, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 7, 7);
typedef std::vector<Marker> markers_vector; findContours(thresh, contours, 40);
isolateMarkers(contours, markers);
class Marker{ for(int i = 0; i < markers.size(); i++){
public: warpMarker(markers[i], gray, mark);
~Marker();
points_vector points;
int code;
};
float perimeter(points_vector &); int code = decodeMarker(mark);
int hammDistMarker(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 &);
void fixCorners(cv::Mat &, Marker &);
void isolateMarkers(const contours_vector &, markers_vector &);
void getAllMarkers(std::vector<int> & codes, cv::Mat & img){ if(code != -1){
cv::Mat gray, thresh, cont, mark; markers[i].code = code;
contours_vector contours; valid_markers.push_back(markers[i]);
markers_vector markers; }
markers_vector valid_markers; }
codes.clear(); for(int i = 0; i < valid_markers.size(); i++){
#ifdef DESKTOP
oss << valid_markers[i].code;
cv::cvtColor(img, gray, CV_BGR2GRAY); cv::putText(mark, oss.str(), cv::Point(5, 250), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(128), 3, 8);
binarize(gray, thresh);
findContours(thresh, contours, 40);
isolateMarkers(contours, markers);
for(int i = 0; i < markers.size(); i++){ oss.str("");
warpMarker(markers[i], gray, mark); oss.clear();
int code = decodeMarker(mark); oss << "Marker[" << i << "]";
if(code != -1){ cv::imshow(oss.str(), mark);
markers[i].code = code;
valid_markers.push_back(markers[i]);
}
}
for(int i = 0; i < valid_markers.size(); i++) oss.str("");
fixCorners(gray, valid_markers[i]); oss.clear();
#endif
cv::cornerSubPix(gray, valid_markers[i].points, cvSize(10, 10), cvSize(-1, -1), termCriteria);
codes.push_back(valid_markers[i].code);
}
cont = cv::Mat::zeros(img.size(), CV_8UC3); cont = cv::Mat::zeros(img.size(), CV_8UC3);
renderMarkers(valid_markers, cont); renderMarkers(valid_markers, cont);
img = img + cont; img = img + cont;
for(int i = 0; i < valid_markers.size(); i++){ markers.clear();
codes.push_back(valid_markers[i].code); contours.clear();
} valid_markers.clear();
}
markers.clear(); void calibrateCamera(cv::Mat & img){
contours.clear(); bool patternfound;
valid_markers.clear(); points_vector corners;
} cv::Mat gray;
#ifdef DESKTOP cv::cvtColor(img, gray, CV_BGR2GRAY);
void getAllMarkers_d(std::vector<int> & codes, cv::Mat & img){ patternfound = cv::findChessboardCorners(gray, checkersPatternSize, corners, PATTERN_DETECTION_PARAMS);
cv::Mat gray, thresh, cont, mark;
contours_vector contours;
markers_vector markers;
markers_vector valid_markers;
std::ostringstream oss;
codes.clear(); if(patternfound)
cv::cornerSubPix(gray, corners, cv::Size(11, 11), cv::Size(-1, -1), termCriteria);
cv::cvtColor(img, gray, CV_BGR2GRAY); cv::drawChessboardCorners(img, checkersPatternSize, cv::Mat(corners), patternfound);
binarize(gray, thresh); }
findContours(thresh, contours, 40);
isolateMarkers(contours, markers);
for(int i = 0; i < markers.size(); i++){ void findContours(cv::Mat & img, contours_vector & v, int minP){
warpMarker(markers[i], gray, mark); std::vector<std::vector<cv::Point> > c;
cv::findContours(img, c, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
int code = decodeMarker(mark); v.clear();
for(size_t i = 0; i < c.size(); i++){
if(c[i].size() > minP){
v.push_back(c[i]);
}
}
}
if(code != -1){ void renderMarkers(markers_vector & v, cv::Mat & dst){
markers[i].code = code; contours_vector cv;
valid_markers.push_back(markers[i]);
}
}
for(int i = 0; i < valid_markers.size(); i++) for(size_t i = 0; i < v.size(); i++){
fixCorners(gray, valid_markers[i]); std::vector<cv::Point> pv;
for(size_t j = 0; j < v[i].points.size(); ++j)
pv.push_back(cv::Point2f(v[i].points[j].x, v[i].points[j].y));
cv.push_back(pv);
}
cont = cv::Mat::zeros(img.size(), CV_8UC3); cv::drawContours(dst, cv, -1, COLOR, 1, CV_AA);
renderMarkers(valid_markers, cont); }
img = img + cont; void isolateMarkers(const contours_vector & vc, markers_vector & vm){
std::vector<cv::Point> appCurve;
markers_vector posMarkers;
for(int i = 0; i < valid_markers.size(); i++){ for(size_t i = 0; i < vc.size(); ++i){
oss << valid_markers[i].code; double eps = vc[i].size() * 0.05;
cv::approxPolyDP(vc[i], appCurve, eps, true);
cv::putText(mark, oss.str(), cv::Point(5, 250), cv::FONT_HERSHEY_PLAIN, 2, cv::Scalar::all(128), 3, 8); if(appCurve.size() != 4 || !cv::isContourConvex(appCurve)) continue;
oss.str(""); float minD = std::numeric_limits<float>::max();
oss.clear();
oss << "Marker[" << i << "]"; for(int i = 0; i < 4; i++){
cv::Point side = appCurve[i] - appCurve[(i + 1) % 4];
float sqSideLen = side.dot(side);
minD = std::min(minD, sqSideLen);
}
cv::imshow(oss.str(), mark); if(minD < MIN_CONTOUR_LENGTH) continue;
oss.str(""); Marker m;
oss.clear();
codes.push_back(valid_markers[i].code); for(int i = 0; i < 4; i++)
} m.points.push_back(cv::Point2f(appCurve[i].x, appCurve[i].y));
markers.clear(); cv::Point v1 = m.points[1] - m.points[0];
contours.clear(); cv::Point v2 = m.points[2] - m.points[0];
valid_markers.clear();
}
#endif
void binarize(cv::Mat & src, cv::Mat & dst){ double o = (v1.x * v2.y) - (v1.y * v2.x);
cv::adaptiveThreshold(src, dst, 255, cv::ADAPTIVE_THRESH_MEAN_C, cv::THRESH_BINARY_INV, 7, 7); if(o < 0.0) std::swap(m.points[1], m.points[3]);
}
void findContours(cv::Mat & img, contours_vector & v, int minP){ posMarkers.push_back(m);
std::vector<std::vector<cv::Point> > c; }
cv::findContours(img, c, CV_RETR_LIST, CV_CHAIN_APPROX_NONE);
v.clear(); std::vector<std::pair<int, int> > tooNear;
for(size_t i = 0; i < c.size(); i++){ for(size_t i = 0; i < posMarkers.size(); ++i){
if(c[i].size() > minP){ const Marker & m1 = posMarkers[i];
v.push_back(c[i]);
}
}
}
void renderContours(contours_vector & v, cv::Mat & dst){ for(size_t j = i + 1; j < posMarkers.size(); j++){
cv::drawContours(dst, v, -1, COLOR, 1, CV_AA); const Marker & m2 = posMarkers[j];
}
void renderMarkers(markers_vector & v, cv::Mat & dst){ float dSq = 0.0f;
contours_vector cv;
for(size_t i = 0; i < v.size(); i++){ for(int c = 0; c < 4; c++){
std::vector<cv::Point> pv; cv::Point v = m1.points[c] - m2.points[c];
for(size_t j = 0; j < v[i].points.size(); ++j) dSq += v.dot(v);
pv.push_back(cv::Point2f(v[i].points[j].x, v[i].points[j].y)); }
cv.push_back(pv);
}
cv::drawContours(dst, cv, -1, COLOR, 1, CV_AA); dSq /= 4.0f;
}
void isolateMarkers(const contours_vector & vc, markers_vector & vm){ if(dSq < 100) tooNear.push_back(std::pair<int, int>(i, j));
std::vector<cv::Point> appCurve; }
markers_vector posMarkers; }
for(size_t i = 0; i < vc.size(); ++i){ std::vector<bool> remMask(posMarkers.size(), false);
double eps = vc[i].size() * 0.05;
cv::approxPolyDP(vc[i], appCurve, eps, true);
if(appCurve.size() != 4 || !cv::isContourConvex(appCurve)) continue; for(size_t i = 0; i < tooNear.size(); ++i){
float p1 = perimeter(posMarkers[tooNear[i].first].points);
float p2 = perimeter(posMarkers[tooNear[i].second].points);
float minD = std::numeric_limits<float>::max(); size_t remInd;
if(p1 > p2) remInd = tooNear[i].second;
else remInd = tooNear[i].first;
for(int i = 0; i < 4; i++){ remMask[remInd] = true;
cv::Point side = appCurve[i] - appCurve[(i + 1) % 4]; }
float sqSideLen = side.dot(side);
minD = std::min(minD, sqSideLen);
}
if(minD < MIN_CONTOUR_LENGTH) continue; vm.clear();
for(size_t i = 0; i < posMarkers.size(); ++i){
if(remMask[i]) vm.push_back(posMarkers[i]);
}
}
Marker m; void warpMarker(Marker & m, cv::Mat & in, cv::Mat & out){
cv::Mat bin;
cv::Size markerSize(350, 350);
points_vector v;
v.push_back(cv::Point2f(0,0));
v.push_back(cv::Point2f(markerSize.width-1,0));
v.push_back(cv::Point2f(markerSize.width-1,markerSize.height-1));
v.push_back(cv::Point2f(0,markerSize.height-1));
for(int i = 0; i < 4; i++) cv::Mat M = cv::getPerspectiveTransform(m.points, v);
m.points.push_back(cv::Point2f(appCurve[i].x, appCurve[i].y)); cv::warpPerspective(in, bin, M, markerSize);
cv::Point v1 = m.points[1] - m.points[0]; cv::threshold(bin, out, 128, 255, cv::THRESH_BINARY | cv::THRESH_OTSU);
cv::Point v2 = m.points[2] - m.points[0]; }
double o = (v1.x * v2.y) - (v1.y * v2.x); int hammDistMarker(cv::Mat bits){
if(o < 0.0) std::swap(m.points[1], m.points[3]); int ids[4][5] = {
{1,0,0,0,0},
{1,0,1,1,1},
{0,1,0,0,1},
{0,1,1,1,0}
};
posMarkers.push_back(m); int dist = 0;
}
std::vector<std::pair<int, int> > tooNear; for (int y = 0; y < 5; y++){
for(size_t i = 0; i < posMarkers.size(); ++i){ int minSum = 1e5;
const Marker & m1 = posMarkers[i];
for(size_t j = i + 1; j < posMarkers.size(); j++){ for (int p = 0; p < 4; p++){
const Marker & m2 = posMarkers[j]; int sum = 0;
float dSq = 0.0f; for (int x = 0; x < 5; x++){
sum += bits.at<uchar>(y, x) == ids[p][x] ? 0 : 1;
}
for(int c = 0; c < 4; c++){ if(minSum > sum)
cv::Point v = m1.points[c] - m2.points[c]; minSum = sum;
dSq += v.dot(v); }
}
dSq /= 4.0f; dist += minSum;
}
if(dSq < 100) tooNear.push_back(std::pair<int, int>(i, j)); return dist;
} }
}
std::vector<bool> remMask(posMarkers.size(), false); cv::Mat rotate(cv::Mat in){
cv::Mat out;
in.copyTo(out);
for (int i=0;i<in.rows;i++){
for (int j=0;j<in.cols;j++){
out.at<uchar>(i,j)=in.at<uchar>(in.cols-j-1,i);
}
}
for(size_t i = 0; i < tooNear.size(); ++i){ return out;
float p1 = perimeter(posMarkers[tooNear[i].first].points); }
float p2 = perimeter(posMarkers[tooNear[i].second].points);
size_t remInd; int decodeMarker(cv::Mat & marker){
if(p1 > p2) remInd = tooNear[i].second; bool found = false;
else remInd = tooNear[i].first; int code = 0;
cv::Mat bits;
remMask[remInd] = true; for(int y = 0; y < 7; y++){
} int inc = (y == 0 || y == 6) ? 1 : 6;
vm.clear(); for(int x = 0; x < 7; x += inc){
for(size_t i = 0; i < posMarkers.size(); ++i){ int cX = x * 50;
if(remMask[i]) vm.push_back(posMarkers[i]); int cY = y * 50;
}
}
void warpMarker(Marker & m, cv::Mat & in, cv::Mat & out){ cv::Mat cell = marker(cv::Rect(cX, cY, 50, 50));
cv::Mat bin;
cv::Size markerSize(350, 350);
points_vector v;
v.push_back(cv::Point2f(0,0));
v.push_back(cv::Point2f(markerSize.width-1,0));
v.push_back(cv::Point2f(markerSize.width-1,markerSize.height-1));
v.push_back(cv::Point2f(0,markerSize.height-1));
cv::Mat M = cv::getPerspectiveTransform(m.points, v); int nZ = cv::countNonZero(cell);
cv::warpPerspective(in, bin, M, markerSize);
cv::threshold(bin, out, 128, 255, cv::THRESH_BINARY | cv::THRESH_OTSU); // Not a valid marker.
} if(nZ > (50 * 50) / 2) return -1;
}
}
int hammDistMarker(cv::Mat bits){ bits = cv::Mat::zeros(5, 5, CV_8UC1);
int ids[4][5] = {
{1,0,0,0,0},
{1,0,1,1,1},
{0,1,0,0,1},
{0,1,1,1,0}
};
int dist = 0;
for (int y = 0; y < 5; y++){ for(int y = 0; y < 5; y++){
int minSum = 1e5; for(int x = 0; x < 5; x++){
int cX = (x + 1) * 50;
int cY = (y + 1) * 50;
for (int p = 0; p < 4; p++){ cv::Mat cell = marker(cv::Rect(cX, cY, 50, 50));
int sum = 0;
for (int x = 0; x < 5; x++){ int nZ = cv::countNonZero(cell);
sum += bits.at<uchar>(y, x) == ids[p][x] ? 0 : 1;
}
if(minSum > sum) if(nZ > (50 * 50) / 2) bits.at<uchar>(y, x) = 1;
minSum = sum; }
} }
dist += minSum; if(hammDistMarker(bits) != 0){
} for(int r = 1; r < 4; r++){
bits = rotate(bits);
if(hammDistMarker(bits) != 0) continue;
else{ found = true; break;}
}
}else found = true;
return dist;
}
cv::Mat rotate(cv::Mat in){
cv::Mat out;
in.copyTo(out);
for (int i=0;i<in.rows;i++){
for (int j=0;j<in.cols;j++){
out.at<uchar>(i,j)=in.at<uchar>(in.cols-j-1,i);
}
}
return out; if(found){
} for(int y = 0; y < 5; y++){
code <<= 1;
if(bits.at<uchar>(y, 1))
code |= 1;
int decodeMarker(cv::Mat & marker){ code <<= 1;
bool found = false; if(bits.at<uchar>(y, 3))
int code = 0; code |= 1;
cv::Mat bits; }
for(int y = 0; y < 7; y++){
int inc = (y == 0 || y == 6) ? 1 : 6;
for(int x = 0; x < 7; x += inc){ return code;
int cX = x * 50; }else
int cY = y * 50; return -1;
}
cv::Mat cell = marker(cv::Rect(cX, cY, 50, 50)); float perimeter(points_vector & p){
float per = 0.0f, dx, dy;
int nZ = cv::countNonZero(cell); for(size_t i; i < p.size(); ++i){
dx = p[i].x - p[(i + 1) % p.size()].x;
dy = p[i].y - p[(i + 1) % p.size()].y;
per += sqrt((dx * dx) + (dy * dy));
}
// Not a valid marker. return per;
if(nZ > (50 * 50) / 2) return -1; }
}
}
bits = cv::Mat::zeros(5, 5, CV_8UC1); Marker::~Marker(){
points.clear();
}
for(int y = 0; y < 5; y++){
for(int x = 0; x < 5; x++){
int cX = (x + 1) * 50;
int cY = (y + 1) * 50;
cv::Mat cell = marker(cv::Rect(cX, cY, 50, 50));
int nZ = cv::countNonZero(cell);
if(nZ > (50 * 50) / 2) bits.at<uchar>(y, x) = 1;
}
}
if(hammDistMarker(bits) != 0){
for(int r = 1; r < 4; r++){
bits = rotate(bits);
if(hammDistMarker(bits) != 0) continue;
else{ found = true; break;}
}
}else found = true;
if(found){
for(int y = 0; y < 5; y++){
code <<= 1;
if(bits.at<uchar>(y, 1))
code |= 1;
code <<= 1;
if(bits.at<uchar>(y, 3))
code |= 1;
}
return code;
}else
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 per = 0.0f, dx, dy;
for(size_t i; i < p.size(); ++i){
dx = p[i].x - p[(i + 1) % p.size()].x;
dy = p[i].y - p[(i + 1) % p.size()].y;
per += sqrt((dx * dx) + (dy * dy));
}
return per;
}
Marker::~Marker(){
points.clear();
}
} }

View File

@@ -20,10 +20,22 @@
#include <opencv2/opencv.hpp> #include <opencv2/opencv.hpp>
namespace nxtar{ namespace nxtar{
void getAllMarkers(std::vector<int> &, cv::Mat &);
#ifdef DESKTOP class Marker;
void getAllMarkers_d(std::vector<int> &, cv::Mat &);
#endif 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 calibrateCamera(cv::Mat &);
} }
#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);