From 6dd78fbe210cf11ec70b89940bf8d128c29cb9df Mon Sep 17 00:00:00 2001 From: "y.qiu" Date: Fri, 30 Aug 2024 20:57:12 +0800 Subject: [PATCH] support rect roi --- grayMatch.cpp | 41 +++++++++++++++++++++++++++++------------ grayMatch.h | 20 +++++++++++++++----- main.cpp | 9 +++++---- serialize.cpp | 2 +- 4 files changed, 50 insertions(+), 22 deletions(-) diff --git a/grayMatch.cpp b/grayMatch.cpp index 63d1724..cc0ca98 100644 --- a/grayMatch.cpp +++ b/grayMatch.cpp @@ -261,7 +261,7 @@ void coeffDenominator(const cv::Mat &src, const cv::Size &templateSize, cv::Mat #ifdef CV_SIMD float convSimd(const uchar *kernel, const uchar *src, const int kernelWidth) { - const auto blockSize = cv::VTraits::vlanes(); + const auto blockSize = cv::v_uint8::nlanes; auto vSum = cv::vx_setall_u32(0); int i = 0; for (; i < kernelWidth - blockSize; i += blockSize) { @@ -695,8 +695,8 @@ std::vector matchModel(const cv::Mat &dst, const Model *model, int level, } Model_t trainModel(const unsigned char *data, int width, int height, int channels, int bytesPerline, - int levelNum) { - if (1 != channels && 3 == channels && 4 == channels) { + int roiLeft, int roiTop, int roiWidth, int roiHeight, int levelNum) { + if (1 != channels && 3 == channels && 4 == channels || nullptr == data) { return nullptr; } @@ -708,17 +708,25 @@ Model_t trainModel(const unsigned char *data, int width, int height, int channel ? src = img : cv::cvtColor(img, src, channels == 3 ? cv::COLOR_RGB2GRAY : cv::COLOR_RGBA2GRAY); - return trainModel(src, levelNum); + cv::Rect rect(roiLeft, roiTop, roiWidth, roiHeight); + cv::Rect imageRect(0, 0, width, height); + auto roi = rect & imageRect; + if (roi.empty()) { + return nullptr; + } + + return trainModel(src(roi), levelNum); } void matchModel(const unsigned char *data, int width, int height, int channels, int bytesPerline, - const Model_t model, int *count, Pose *poses, int level, double startAngle, - double spanAngle, double maxOverlap, double minScore, int subpixel) { + int roiLeft, int roiTop, int roiWidth, int roiHeight, const Model_t model, + int *count, Pose *poses, int level, double startAngle, double spanAngle, + double maxOverlap, double minScore, int subpixel) { if (nullptr == count) { return; } - if (nullptr == poses) { + if (nullptr == poses || nullptr == data) { *count = 0; return; } @@ -736,24 +744,33 @@ void matchModel(const unsigned char *data, int width, int height, int channels, ? dst = img : cv::cvtColor(img, dst, channels == 3 ? cv::COLOR_RGB2GRAY : cv::COLOR_RGBA2GRAY); - auto result = matchModel(dst, model, level, startAngle, spanAngle, maxOverlap, minScore, *count, - subpixel); + cv::Rect rect(roiLeft, roiTop, roiWidth, roiHeight); + cv::Rect imageRect(0, 0, width, height); + auto roi = rect & imageRect; + if (roi.empty()) { + *count = 0; + return; + } + + auto result = matchModel(dst(roi), model, level, startAngle, spanAngle, maxOverlap, minScore, + *count, subpixel); auto size = std::min(*count, static_cast(result.size())); for (int i = 0; i < size; i++) { - poses[ i ] = result[ i ]; + const auto &pose = result[ i ]; + poses[ i ] = {pose.x + roi.x, pose.y + roi.y, pose.angle, pose.score}; } *count = size; } void freeModel(Model_t *model) { - if (nullptr == model) { + if (nullptr == model || nullptr == *model) { return; } delete *model; - model = nullptr; + *model = nullptr; } int modelLevel(const Model_t model) { diff --git a/grayMatch.h b/grayMatch.h index e84ff83..669196c 100644 --- a/grayMatch.h +++ b/grayMatch.h @@ -21,11 +21,16 @@ struct Pose { * @param height image height * @param channels image channels 1(gray)/3(rgb)/4(rgba) * @param bytesPerline bytes per line + * @param roiLeft rectangle roi left + * @param roiTop rectangle roi top + * @param roiWidth rectangle roi width + * @param roiHeight rectangle roi height * @param levelNum pyramid levels (> 0) - * @return model + * @return */ API_PUBLIC Model_t trainModel(const unsigned char *data, int width, int height, int channels, - int bytesPerline, int levelNum); + int bytesPerline, int roiLeft, int roiTop, int roiWidth, + int roiHeight, int levelNum); /** * @brief match model * @param data image data @@ -33,6 +38,10 @@ API_PUBLIC Model_t trainModel(const unsigned char *data, int width, int height, * @param height image height * @param channels image channels 1(gray)/3(rgb)/4(rgba) * @param bytesPerline bytes per line + * @param roiLeft rectangle roi left + * @param roiTop rectangle roi top + * @param roiWidth rectangle roi width + * @param roiHeight rectangle roi height * @param model trained model * @param count in(max detect count)/out(found count) * @param poses pose array inited with size not less than count @@ -45,9 +54,10 @@ API_PUBLIC Model_t trainModel(const unsigned char *data, int width, int height, * @return */ API_PUBLIC void matchModel(const unsigned char *data, int width, int height, int channels, - int bytesPerline, const Model_t model, int *count, Pose *poses, - int level, double startAngle, double spanAngle, double maxOverlap, - double minScore, int subpixel); + int bytesPerline, int roiLeft, int roiTop, int roiWidth, int roiHeight, + const Model_t model, int *count, Pose *poses, int level, + double startAngle, double spanAngle, double maxOverlap, double minScore, + int subpixel); /** * @brief get trained model levels diff --git a/main.cpp b/main.cpp index 070726c..018a74e 100644 --- a/main.cpp +++ b/main.cpp @@ -10,7 +10,8 @@ int main() { cv::imread("C:/Users/qiuyong/Desktop/test/template/model3_src1.bmp", cv::IMREAD_GRAYSCALE); auto t0 = cv::getTickCount(); - auto model = trainModel(src.data, src.cols, src.rows, src.channels(), int(src.step), -1); + auto model = trainModel(src.data, src.cols, src.rows, src.channels(), int(src.step), 0, 0, + src.cols, src.rows, -1); auto t1 = cv::getTickCount(); int size; @@ -26,8 +27,8 @@ int main() { std::vector poses(num); auto t2 = cv::getTickCount(); - matchModel(dst.data, dst.cols, dst.rows, dst.channels(), int(dst.step), model, &num, - poses.data(), -1, 0, 360, 0, 0.5, 1); + matchModel(dst.data, dst.cols, dst.rows, dst.channels(), int(dst.step), 0, 0, dst.cols, + dst.rows, model, &num, poses.data(), -1, 0, 360, 0, 0.5, 1); auto t3 = cv::getTickCount(); auto trainCost = double(t1 - t0) / cv::getTickFrequency(); @@ -40,7 +41,7 @@ int main() { auto &pose = poses[ i ]; cv::RotatedRect rect(cv::Point2f(pose.x, pose.y), src.size(), -pose.angle); - std::vector pts; + cv::Point2f pts[ 4 ]; rect.points(pts); cv::line(color, pts[ 0 ], pts[ 1 ], cv::Scalar(255, 0, 0), 1, cv::LINE_AA); diff --git a/serialize.cpp b/serialize.cpp index f2d673b..1a47f18 100644 --- a/serialize.cpp +++ b/serialize.cpp @@ -182,7 +182,7 @@ public: }; void operation(Buffer *buf, Model &model) { - buf->operator&(model); + (*buf) & (model); } bool serialize(const Model_t model, unsigned char *buffer, int *size) {