我是Android + OpenCV + JNI开发的新手。我试图找出最大的轮廓 这是我的原生代码:
JNIEXPORT jint JNICALL
Java_org_opencv_samples_tutorial3_Sample3Native_FindSquares
(JNIEnv* env, jobject, jlong addrRgba, jint draw) {
Mat& image = *(Mat*) addrRgba;
int thresh = 50, N = 4;
int found = 0;
Mat pyr, timg, gray0(image.size(), CV_8U), gray;
pyrDown(image, pyr, Size(image.cols / 2, image.rows / 2));
pyrUp(pyr, timg, image.size());
vector < vector<Point> > contours;
// find squares in every color plane of the image
for (int c = 1; c < 3; c++) {
int ch[] = { c, 0 };
mixChannels(&timg, 1, &gray0, 1, ch, 1);
// try several threshold levels
for (int l = 0; l < N; l++) {
// hack: use Canny instead of zero threshold level.
// Canny helps to catch squares with gradient shading
if (l == 0) {
// apply Canny. Take the upper threshold from slider
// and set the lower to 0 (which forces edges merging)
Canny(gray0, gray, 0, thresh, 5);
// dilate canny output to remove potential
// holes between edge segments
dilate(gray, gray, Mat(), Point(-1, -1));
} else {
// apply threshold if l!=0:
// tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
gray = gray0 >= (l + 1) * 255 / N;
}
// find contours and store them all as a list
findContours(gray, contours, CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE);
vector<Point> approx;
// test each contour
for (size_t i = 0; i < contours.size(); i++) {
// approximate contour with accuracy proportional
// to the contour perimeter
approxPolyDP(Mat(contours[i]), approx,
arcLength(Mat(contours[i]), true) * 0.02, true);
// square contours should have 4 vertices after approximation
// relatively large area (to filter out noisy contours)
// and be convex.
// Note: absolute value of an area is used because
// area may be positive or negative - in accordance with the
// contour orientation
if (approx.size() == 4 && fabs(contourArea(Mat(approx))) > 1000
&& isContourConvex(Mat(approx))) {
double maxCosine = 0;
for (int j = 2; j < 5; j++) {
// find the maximum cosine of the angle between joint edges
double cosine = fabs(
angle(approx[j % 4], approx[j - 2],
approx[j - 1]));
maxCosine = MAX(maxCosine, cosine);
}
// if cosines of all angles are small
// (all angles are ~90 degree) then write quandrange
// vertices to resultant sequence
if (maxCosine < 0.3) {
circle(image, approx[0], 5, Scalar(255, 0, 0, 255), 3,
4, 0);
circle(image, approx[1], 5, Scalar(255, 0, 0, 255), 3,
4, 0);
circle(image, approx[2], 5, Scalar(255, 0, 0, 255), 3,
4, 0);
circle(image, approx[3], 5, Scalar(255, 0, 0, 255), 3,
4, 0);
//rectangle(image, approx[0], approx[2], Scalar(0,255,0,255), 5, 4, 0);
//Center of this rectangle
int x = (int) ((approx[0].x + approx[1].x + approx[2].x
+ approx[3].x) / 4.0);
int y = (int) ((approx[0].y + approx[1].y + approx[2].y
+ approx[3].y) / 4.0);
if ((int) draw) {
//outline
line(image, approx[0], approx[1],
Scalar(0, 255, 0, 255), 1, 4, 0);
line(image, approx[1], approx[2],
Scalar(0, 255, 0, 255), 1, 4, 0);
line(image, approx[2], approx[3],
Scalar(0, 255, 0, 255), 1, 4, 0);
line(image, approx[3], approx[0],
Scalar(0, 255, 0, 255), 1, 4, 0);
}
/// Get the moments
vector<Moments> mu(contours.size());
for (int i = 0; i < contours.size(); i++) {
mu[i] = moments(contours[i], false);
}
/// Get the mass centers:
vector<Point2f> mc(contours.size());
for (int i = 0; i < contours.size(); i++) {
mc[i] = Point2f(mu[i].m10 / mu[i].m00,
mu[i].m01 / mu[i].m00);
}
/// Draw contours
for (int i = 0; i < contours.size(); i++) {
circle(image, mc[i], 10, Scalar(255, 0, 0), 1,
CV_AA, 0);
}
found = 1;
jint result = (jint) found;
return result;
}
}
}
}
}
jint result = (jint) found;
return result;
}
我 我从java代码中调用这个本机方法为
public native void FindFeatures(long matAddrGr, long matAddrRgba);
一切都适合我。我从本机代码Java代码返回int。我怀疑的是如何从原生代码向Java返回vector(我的方法中的'mc'对象)。请帮我找出从JNI返回向量列表的方法。
答案 0 :(得分:3)
vector<Point2f>
对应于Java中的MatOfPoint2f
,它是Mat
的派生类。
使用vector
至Mat
转换功能,如在opencv repo(1)中
void vector_Point2f_to_Mat(vector<Point2f>& v_point, Mat& mat)
{
mat = Mat(v_point, true);
}