Kotlin: 17fps
fun drawFaceRectangle() {
faceRects = MatOfRect()
// image width & height
val scrW = grayMat.width().toDouble()
val scrH = grayMat.height().toDouble()
val scale = getRatio(Size(scrW, scrH), 480) + 1
val neighbor = 3
rotateImage()
faceDetector!!.detectMultiScale(
grayMat, // image
faceRects, // array
scale, // scale
neighbor, // min neighbors
0, // flags,
Size(30.0, 30.0), // min size
Size(scrW, scrH) // max size
)
for (rect in faceRects!!.toArray()) {
val x = rect.x.toDouble()
val y = rect.y.toDouble()
val rw = rect.width.toDouble() // rectangle width
val rh = rect.height.toDouble() // rectangle height
val w = x + rw
val h = y + rh
when (screenRotation) {
0-> {
rectFace(y, x, h, w, RED)
drawDot(y, x, GREEN)
}
90-> {
rectFace(x, y, w, h, RED)
drawDot(x, y, GREEN)
}
180-> {
// fix height
val yFix = scrW - y
val hFix = yFix - rh
rectFace(yFix, x, hFix, w, YELLOW)
drawDot(yFix, x, BLUE)
}
270-> {
// fix height
val yFix = scrH - y
val hFix = yFix - rh
rectFace(x, yFix, w, hFix, YELLOW)
drawDot(x, yFix, BLUE)
}
}
}
}
ndk: 9fps
void drawFaceRectangle(
Mat &rgba,
Mat &gray,
String path,
double ratio,
int rotation) {
// width and height of frame
float scrW = (float)rgba.size().width;
float scrH = (float)rgba.size().height;
vector<cv::Rect> faces;
double scale = 1.0+ratio;
int neighbor = 3;
// fix orientation so it can be detected
rotateGray(gray, rotation);
/*
* void detectMultiScale (
* InputArray image,
* std::vector< Rect > &objects,
* double scaleFactor=1.1,
* int minNeighbors=3,
* int flags=0,
* Size minSize=Size(),
* Size maxSize=Size())
Detects objects of different sizes in the input image.
The detected objects are returned as a list of rectangles.
*/
faceDetector.detectMultiScale(
gray, // image
faces, // array
scale, // scale
neighbor, // min neighbors
0, // flags,
Size(30, 30), // min size
Size((int)scrW, (int)scrH) // max size
);
for (int i=0; i<faces.size(); i++) {
Rect rect = faces[i];
float x = (float)rect.x;
float y = (float)rect.y;
float rw = (float)rect.width;
float rh = (float)rect.height;
float w = x + rw;
float h = y + rh;
float yFix, hFix;
// draw rectangle
switch (rotation) {
case 0:
rectFace(rgba, y, x, h, w, RED);
drawDot(rgba, y, x, GREEN);
break;
case 90:
rectFace(rgba, x, y, w, h, RED);
drawDot(rgba, x, y, GREEN);
break;
case 180:
// fix height
yFix = scrW - y;
hFix = yFix - rh;
rectFace(rgba, yFix, x, hFix, w, YELLOW);
drawDot(rgba, yFix, x, BLUE);
break;
case 270:
// fix height
yFix = scrH - y;
hFix = yFix - rh;
rectFace(rgba, x, yFix, w, hFix, YELLOW);
drawDot(rgba, x, yFix, BLUE);
break;
default:
string msg = "Error: wrong rotation data -- " +
to_string(rotation);
lge(msg.c_str());
break;
}
}
}
You see, they are same function. The timing are much different.
override fun onCameraFrame(inputFrame: CvCameraViewFrame?): Mat {
if (pCounter == 1000) {
evalPerfomance()
finish()
}
// start time
frameStart = System.currentTimeMillis()
imageMat = inputFrame!!.rgba()
if (!javaEnabled) {
// C++
/*
if (!OpenCvNativeCall().convertGray(
imageMat.nativeObjAddr,
grayMat.nativeObjAddr
)
) {
throw CvException("Data is corrupted!")
}
*/
if (!OpenCvNativeCall().faceDetection(
imageMat.nativeObjAddr,
480,
screenRotation,
faceModel!!.absolutePath)) {
longMsg(this, "Failed to load Face Detector!!!")
}
} else {
grayMat = inputFrame!!.gray()
// detect face rectangle
drawFaceRectangle()
}
postText("$pCounter", 100.0, 100.0, YELLOW)
// end time
frameEnd = System.currentTimeMillis()
frameRecord[pCounter] = frameEnd - frameStart
pCounter++
return imageMat
}
fun evalPerfomance() {
val avg = frameRecord.average()
lgd("Java Enable? $javaEnabled ... Runtime average = $avg ms")
}
The logcat came back with NDK is much slower.
7204-7204 D/MYLOG MainActivity: OpenCV started...
7204-7204 I/MYLOG MainActivity: OpenCV Loaded Successfully!
7204-7204 D/MYLOG MainActivity: OpenCV started...
7204-7204 D/MYLOG MainActivity: CameraView turned ON...
7204-7204 D/MYLOG MainActivity: System Ui Visibility Change
7204-7239 D/MYLOG MainActivity: Java Enable? true ... Runtime average = 39.043 ms
7510-7510 D/MYLOG MainActivity: OpenCV started...
7510-7510 I/MYLOG MainActivity: OpenCV Loaded Successfully!
7510-7510 D/MYLOG MainActivity: OpenCV started...
7510-7510 D/MYLOG MainActivity: CameraView turned ON...
7510-7510 D/MYLOG MainActivity: System Ui Visibility Change
7510-7547 D/MYLOG MainActivity: Java Enable? false ... Runtime average = 88.269 ms
How can I make the C++ code faster? (OpenCV library 4.3.0)