Skip to content

Commit

Permalink
Fix a possible crash when detecting really small conditions
Browse files Browse the repository at this point in the history
  • Loading branch information
Nain57 committed Jun 1, 2024
1 parent 4168742 commit 632af16
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 10 deletions.
24 changes: 18 additions & 6 deletions core/smart/detection/src/main/cpp/detector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -79,29 +79,39 @@ DetectionResult Detector::detectCondition(JNIEnv *env, jobject conditionImage, c
}

// Get and check the detection area in normal and scaled size
if (isRoiContainedInImage(fullSizeDetectionRoi, *fullSizeColorCurrentImage)) {
if (isRoiNotContainedInImage(fullSizeDetectionRoi, *fullSizeColorCurrentImage)) {
logInvalidRoiInImage(fullSizeDetectionRoi, *fullSizeColorCurrentImage);
return detectionResult;
}
auto scaledDetectionRoi = getScaledRoi(fullSizeDetectionRoi, scaleRatio);
if (isRoiContainedInImage(scaledDetectionRoi, *scaledGrayCurrentImage)) {
if (isRoiNotContainedInImage(scaledDetectionRoi, *scaledGrayCurrentImage)) {
logInvalidRoiInImage(scaledDetectionRoi, *scaledGrayCurrentImage);
return detectionResult;
}

// Get the condition image information from the android bitmap format.
auto fullSizeColorCondition = createColorMatFromARGB8888BitmapData(env, conditionImage);
if (isRoiContainsImage(fullSizeDetectionRoi, *fullSizeColorCondition)) {

if (isRoiNotContainingImage(fullSizeDetectionRoi, *fullSizeColorCondition)) {
logInvalidRoiInImage(fullSizeDetectionRoi, *fullSizeColorCondition);
return detectionResult;
}
auto scaledGrayCondition = scaleAndChangeToGray(*fullSizeColorCondition);
if (isRoiContainsImage(scaledDetectionRoi, *scaledGrayCondition)) {
if (isRoiNotContainingImage(scaledDetectionRoi, *scaledGrayCondition)) {
logInvalidRoiInImage(scaledDetectionRoi, *scaledGrayCondition);
return detectionResult;
}
// Crop the scaled gray current image to only get the detection area
auto croppedGrayCurrentImage = Mat(*scaledGrayCurrentImage, scaledDetectionRoi);
if (isImageNotContainingImage(croppedGrayCurrentImage, *scaledGrayCondition)) {
__android_log_print(
ANDROID_LOG_ERROR, "Detector",
"Condition is bigger than screen image, [%1d;%2d] [%3d;%4d]",
croppedGrayCurrentImage.cols, croppedGrayCurrentImage.rows,
scaledGrayCondition->cols, scaledGrayCondition->rows
);
return detectionResult;
}

// Get the matching results
auto matchingResults = matchTemplate(croppedGrayCurrentImage, *scaledGrayCondition);
Expand All @@ -117,8 +127,8 @@ DetectionResult Detector::detectCondition(JNIEnv *env, jobject conditionImage, c
// Calculate the ROI based on the maximum location
scaledMatchingRoi = getRoiForResult(detectionResult.maxLoc, *scaledGrayCondition);
fullSizeMatchingRoi = getDetectionResultFullSizeRoi(fullSizeDetectionRoi, fullSizeColorCondition->cols, fullSizeColorCondition->rows);
if (isRoiContainedInImage(scaledMatchingRoi, *scaledGrayCurrentImage) ||
isRoiContainedInImage(fullSizeMatchingRoi, *fullSizeColorCurrentImage)) {
if (isRoiNotContainedInImage(scaledMatchingRoi, *scaledGrayCurrentImage) ||
isRoiNotContainedInImage(fullSizeMatchingRoi, *fullSizeColorCurrentImage)) {
// Roi is out of bounds, invalid match
detectionResult.centerX = 0;
detectionResult.centerY = 0;
Expand Down Expand Up @@ -164,6 +174,7 @@ std::unique_ptr<Mat> Detector::matchTemplate(const Mat& image, const Mat& condit
cv::Mat resultMat(max(image.rows - condition.rows + 1, 0),
max(image.cols - condition.cols + 1, 0),
CV_32F);

cv::matchTemplate(image, condition, resultMat, cv::TM_CCOEFF_NORMED);

return std::make_unique<cv::Mat>(resultMat);
Expand Down Expand Up @@ -196,3 +207,4 @@ cv::Rect Detector::getDetectionResultFullSizeRoi(const cv::Rect& fullSizeDetecti
fullSizeHeight
};
}

13 changes: 9 additions & 4 deletions core/smart/detection/src/main/cpp/utils/roi.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,14 +18,19 @@

namespace smartautoclicker {

bool isRoiContainedInImage(const cv::Rect& roi, const cv::Mat& image) {
bool isRoiNotContainedInImage(const cv::Rect& roi, const cv::Mat& image) {
return 0 > roi.x || 0 > roi.width || roi.x + roi.width > image.cols
|| 0 > roi.y || 0 > roi.height || roi.y + roi.height > image.rows;
}

bool isRoiContainsImage(const cv::Rect& roi, const cv::Mat& image) {
return roi.x >= 0 && roi.width > 0 && roi.x + roi.width <= image.cols
&& roi.y >= 0 && roi.height > 0 && roi.y + roi.height <= image.rows;
bool isRoiNotContainingImage(const cv::Rect& roi, const cv::Mat& image) {
return roi.x < 0 || roi.width <= 0 || roi.width < image.cols
|| roi.y < 0 || roi.height <= 0 || roi.y + roi.height < image.rows;
}

bool isImageNotContainingImage(const cv::Mat& container, const cv::Mat& contained) {
return container.size().height < contained.size().height ||
container.size().width < contained.size().width;
}

cv::Rect getScaledRoi(const cv::Rect& roi, const double scaleRatio) {
Expand Down

0 comments on commit 632af16

Please sign in to comment.