I’m trying to convert my python file to java for detecting seatbelt detection. so, I get the image. I detect if there is a person in the image using YOLO file. if there has been successfully a person detected, we try to crop it resize it and use a tensorflow model to detect if I have successfully detected a seatbelt or not. The problem comes with resizing of the image. The mat of the resized image fails everytime. imgRoi seems to be not resizing the image by the parameters specified.
def detect_person(image, confThreshold):
img = np.copy(image)
blob = cv2.dnn.blobFromImage(img, 1/255.0, (416, 416), swapRB=True, crop=False)
net.setInput(blob)
outputs = net.forward(names)
outputs = np.vstack(outputs)
H, W = image.shape[:2]
boxes = []
confidences = []
classIDs = []
for output in outputs:
scores = output[5:]
classID = np.argmax(scores)
confidence = scores[classID]
if confidence > confThreshold:
x, y, w, h = output[:4] * np.array([W, H, W, H])
p0 = int(x - w//2), int(y - h//2)
p1 = int(x + w//2), int(y + h//2)
boxes.append([*p0, int(w), int(h)])
confidences.append(float(confidence))
classIDs.append(classID)
indices = cv2.dnn.NMSBoxes(boxes, confidences, confThreshold, confThreshold-0.1)
bboxes = []
confs = []
if len(indices) > 0:
for i in indices.flatten():
(x, y) = (boxes[i][0], boxes[i][1])
(w, h) = (boxes[i][2], boxes[i][3])
# track only people in image
if classIDs[i] == 0:
x0 = max(0,x)
y0 = max(0,y)
x1 = min(x0+w,img.shape[1])
y1 = min(y0+h, img.shape[0])
bboxes.append([x0,y0,x1,y1])
confs.append(round(confidences[i],2))
return bboxes,confs
working fine above code in python no image issue.
I’ve converted the to the above code for android as follows:
val frame = Mat()
val originalMat = Mat()
Utils.bitmapToMat(img, originalMat)
Utils.bitmapToMat(img, frame)
Imgproc.cvtColor(frame, frame, Imgproc.COLOR_RGBA2RGB)
val blob = Dnn.blobFromImage(
frame,
0.00392,
Size(416.0, 416.0),
Scalar(0.0, 0.0, 0.0),/*swapRB*/
true, /*crop*/
false
)
maskModel?.setInput(blob)
val outPutNames = getOutputNames(maskModel!!)
val result: List<Mat> = java.util.ArrayList(outPutNames!!.size)
maskModel!!.forward(result, outPutNames)
val confThreshold = 0.2f
val clsIds: MutableList<Int> = java.util.ArrayList()
val confs: MutableList<Float> = java.util.ArrayList()
val rects: MutableList<Rect> = java.util.ArrayList()
for (i in result.indices) {
val level = result[i]
for (j in 0 until level.rows()) {
val row = level.row(j)
val scores = row.colRange(5, level.cols())
val mm = Core.minMaxLoc(scores)
val confidence = mm.maxVal.toFloat()
val classIdPoint = mm.maxLoc
if (confidence > confThreshold) {
val centerX = (row[0, 0][0] * frame.cols()).toInt()
val centerY = (row[0, 1][0] * frame.rows()).toInt()
val width = (row[0, 2][0] * frame.cols()).toInt()
val height = (row[0, 3][0] * frame.rows()).toInt()
val left = centerX - width / 2
val top = centerY - height / 2
clsIds.add(classIdPoint.x.toInt())
confs.add(confidence)
rects.add(Rect(left, top, width, height))
}
}
}
val ArrayLength = confs.size
if (ArrayLength >= 1) {
// Apply non-maximum suppression procedure.
val nmsThresh = 0.4f
val confidences = MatOfFloat(Converters.vector_float_to_Mat(confs))
val boxesArray = rects.toTypedArray()
val boxes = MatOfRect(*boxesArray)
val indices = MatOfInt()
Dnn.NMSBoxes(
boxes,
confidences,
confThreshold,
(confThreshold - 0.1).toFloat(),
indices
)
// Draw result boxes:
val ind = indices.toArray()
for (i in ind.indices) {
val idx = ind[i]
val box = boxesArray[idx]
val idGuy = clsIds[idx]
val conf = confs[idx]
val intConf = (conf * 100).toInt()
Imgproc.putText(
frame,
labels[idGuy].toString() + " " + intConf + "%",
box.tl(),
Core.FONT_HERSHEY_SIMPLEX,
2.0,
Scalar(255.0, 255.0, 0.0),
2
)
println(
"frame " + "${labels[idGuy]} "
)
imageReceivedEvent.detectedItems?.add(labels[idGuy])
Imgproc.rectangle(frame, box.tl(), box.br(), Scalar(255.0, 0.0, 0.0), 2)
if (idGuy == 0) {
BWLog.i("TRACKING PEOPLE!!", "SUCCESS")
imageReceivedEvent.PersonEnum = BWConstants.PERSON_ENUM.PERSON_DETECTED
imageReceivedEvent.confidence = intConf.toDouble()
if (true ) {
try {
val x = max(0, box.x)
val y = max(0, box.y)
val rows = originalMat.rows()
val cols = originalMat.cols()
val x1 = min(x + box.width, cols)
val y1 = min(y + box.height, rows)
val imgRoi = Mat(
originalMat,
Rect(x, y, x1, y1)
)
val bitmap = preProcessPerson(imgRoi)
detectedPersonBoundingBoxes.add(
BoundingBox(
bitmap,
x, y, x1, y1
)
)
} catch (e: Exception) {
e.printStackTrace()
}
} else {
detectedPersonBoundingBoxes.add(
BoundingBox(
img,
box.x,
box.y,
box.x + box.width, box.y + box.height
)
)
}
} else {
}
}
}
if (detectedPersonBoundingBoxes.isEmpty()) {
// no person found.
//
} else {
recreateMaskDetectorTFLite(
maskModelFloat,
maskDevice,
tfLiteNumThreads
)
// doTensorFlowDetection(detectedPersonBoundingBoxes[0])
}
detectedPersonBoundingBoxes.forEach { boundBox ->
recreateMaskDetectorTFLite(
maskModelFloat,
maskDevice,
tfLiteNumThreads
)
doTensorFlowDetection(boundBox)
}
2021-05-03 12:14:45.534 10932-11085/com.buttonwillow.app E/cv::error(): OpenCV(3.4.6) Error: Assertion failed (0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows) in cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&), file /build/3_4_pack-android/opencv/modules/core/src/matrix.cpp, line 424
2021-05-03 12:14:45.534 10932-11085/com.buttonwillow.app E/org.opencv.core.Mat: Mat::n_1Mat__JIIII() caught cv::Exception: OpenCV(3.4.6) /build/3_4_pack-android/opencv/modules/core/src/matrix.cpp:424: error: (-215:Assertion failed) 0 <= _rowRange.start && _rowRange.start <= _rowRange.end && _rowRange.end <= m.rows in function 'cv::Mat::Mat(const cv::Mat&, const cv::Range&, const cv::Range&)'
)