From 63e4af85365a7ca004fa588e18429e3ffd468c93 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Sun, 29 Dec 2013 02:28:43 +0400 Subject: [PATCH 1/2] added the first T-API example - CamShift tracking --- samples/CMakeLists.txt | 4 +- samples/c/CMakeLists.txt | 2 +- samples/cpp/CMakeLists.txt | 2 +- samples/gpu/CMakeLists.txt | 2 +- samples/ocl/CMakeLists.txt | 7 +- samples/tapi/CMakeLists.txt | 52 +++++++++ samples/tapi/camshift.cpp | 209 ++++++++++++++++++++++++++++++++++++ 7 files changed, 269 insertions(+), 9 deletions(-) create mode 100644 samples/tapi/CMakeLists.txt create mode 100644 samples/tapi/camshift.cpp diff --git a/samples/CMakeLists.txt b/samples/CMakeLists.txt index 9dd3df0b69..01f376dd37 100644 --- a/samples/CMakeLists.txt +++ b/samples/CMakeLists.txt @@ -14,6 +14,7 @@ add_subdirectory(c) add_subdirectory(cpp) add_subdirectory(gpu) add_subdirectory(ocl) +add_subdirectory(tapi) if(WIN32 AND HAVE_DIRECTX) add_subdirectory(directx) @@ -23,7 +24,6 @@ if(ANDROID AND BUILD_ANDROID_EXAMPLES) add_subdirectory(android) endif() - # # END OF BUILD CASE 1: Build samples with library sources # @@ -73,4 +73,4 @@ endif() # # END OF BUILD CASE 2: Build samples with library binaries # -endif() \ No newline at end of file +endif() diff --git a/samples/c/CMakeLists.txt b/samples/c/CMakeLists.txt index 77a42949d0..b8dfe64d19 100644 --- a/samples/c/CMakeLists.txt +++ b/samples/c/CMakeLists.txt @@ -51,7 +51,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endforeach() endif() -if (INSTALL_C_EXAMPLES AND NOT WIN32) +if(INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB C_SAMPLES *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${C_SAMPLES} DESTINATION share/OpenCV/samples/c diff --git a/samples/cpp/CMakeLists.txt b/samples/cpp/CMakeLists.txt index 4b0bf011d9..eaebcb96f1 100644 --- a/samples/cpp/CMakeLists.txt +++ b/samples/cpp/CMakeLists.txt @@ -99,7 +99,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endforeach() endif() -if (INSTALL_C_EXAMPLES AND NOT WIN32) +if(INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB C_SAMPLES *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${C_SAMPLES} DESTINATION share/OpenCV/samples/cpp diff --git a/samples/gpu/CMakeLists.txt b/samples/gpu/CMakeLists.txt index 64c25fc092..1d19fbdd3e 100644 --- a/samples/gpu/CMakeLists.txt +++ b/samples/gpu/CMakeLists.txt @@ -91,7 +91,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) include("performance/CMakeLists.txt") endif() -if (INSTALL_C_EXAMPLES AND NOT WIN32) +if(INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB install_list *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${install_list} DESTINATION share/OpenCV/samples/${project} diff --git a/samples/ocl/CMakeLists.txt b/samples/ocl/CMakeLists.txt index b4f7afa212..9344fb08ca 100644 --- a/samples/ocl/CMakeLists.txt +++ b/samples/ocl/CMakeLists.txt @@ -1,7 +1,6 @@ -SET(OPENCV_OCL_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc opencv_highgui +SET(OPENCV_OCL_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_features2d - opencv_calib3d opencv_legacy opencv_contrib opencv_ocl - opencv_nonfree opencv_bioinspired) + opencv_ocl opencv_nonfree opencv_bioinspired) ocv_check_dependencies(${OPENCV_OCL_SAMPLES_REQUIRED_DEPS}) @@ -51,7 +50,7 @@ if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) endforeach() endif() -if (INSTALL_C_EXAMPLES AND NOT WIN32) +if(INSTALL_C_EXAMPLES AND NOT WIN32) file(GLOB install_list *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) install(FILES ${install_list} DESTINATION share/OpenCV/samples/${project} diff --git a/samples/tapi/CMakeLists.txt b/samples/tapi/CMakeLists.txt new file mode 100644 index 0000000000..4cfb5805bd --- /dev/null +++ b/samples/tapi/CMakeLists.txt @@ -0,0 +1,52 @@ +SET(OPENCV_TAPI_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_video opencv_highgui) + +ocv_check_dependencies(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) + +if(BUILD_EXAMPLES AND OCV_DEPENDENCIES_FOUND) + set(project "tapi") + string(TOUPPER "${project}" project_upper) + + project("${project}_samples") + + ocv_include_modules(${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) + + # --------------------------------------------- + # Define executable targets + # --------------------------------------------- + MACRO(OPENCV_DEFINE_TAPI_EXAMPLE name srcs) + set(the_target "example_${project}_${name}") + add_executable(${the_target} ${srcs}) + + target_link_libraries(${the_target} ${OPENCV_LINKER_LIBS} ${OPENCV_TAPI_SAMPLES_REQUIRED_DEPS}) + + set_target_properties(${the_target} PROPERTIES + OUTPUT_NAME "${project}-example-${name}" + PROJECT_LABEL "(EXAMPLE_${project_upper}) ${name}") + + if(ENABLE_SOLUTION_FOLDERS) + set_target_properties(${the_target} PROPERTIES FOLDER "samples//${project}") + endif() + + if(WIN32) + if(MSVC AND NOT BUILD_SHARED_LIBS) + set_target_properties(${the_target} PROPERTIES LINK_FLAGS "/NODEFAULTLIB:atlthunk.lib /NODEFAULTLIB:atlsd.lib /DEBUG") + endif() + install(TARGETS ${the_target} RUNTIME DESTINATION "${OPENCV_SAMPLES_BIN_INSTALL_PATH}/${project}" COMPONENT main) + endif() + ENDMACRO() + + file(GLOB all_samples RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.cpp) + + foreach(sample_filename ${all_samples}) + get_filename_component(sample ${sample_filename} NAME_WE) + file(GLOB sample_srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${sample}.*) + OPENCV_DEFINE_TAPI_EXAMPLE(${sample} ${sample_srcs}) + endforeach() +endif() + +if(INSTALL_C_EXAMPLES AND NOT WIN32) + file(GLOB install_list *.c *.cpp *.jpg *.png *.data makefile.* build_all.sh *.dsp *.cmd ) + install(FILES ${install_list} + DESTINATION share/OpenCV/samples/${project} + PERMISSIONS OWNER_READ GROUP_READ WORLD_READ) +endif() diff --git a/samples/tapi/camshift.cpp b/samples/tapi/camshift.cpp new file mode 100644 index 0000000000..d6e353253f --- /dev/null +++ b/samples/tapi/camshift.cpp @@ -0,0 +1,209 @@ +#include "opencv2/core/utility.hpp" +#include "opencv2/video/tracking.hpp" +#include "opencv2/imgproc/imgproc.hpp" +#include "opencv2/highgui/highgui.hpp" + +#include +#include + +static cv::Mat image; +static bool backprojMode = false; +static bool selectObject = false; +static int trackObject = 0; +static bool showHist = true; +static cv::Point origin; +static cv::Rect selection; +static int vmin = 10, vmax = 256, smin = 30; + +static void onMouse(int event, int x, int y, int, void*) +{ + if (selectObject) + { + selection.x = std::min(x, origin.x); + selection.y = std::min(y, origin.y); + selection.width = std::abs(x - origin.x); + selection.height = std::abs(y - origin.y); + + selection &= cv::Rect(0, 0, image.cols, image.rows); + } + + switch(event) + { + case cv::EVENT_LBUTTONDOWN: + origin = cv::Point(x, y); + selection = cv::Rect(x, y, 0, 0); + selectObject = true; + break; + case cv::EVENT_LBUTTONUP: + selectObject = false; + if (selection.width > 0 && selection.height > 0) + trackObject = -1; + break; + default: + break; + } +} + +static void help() +{ + std::cout << "\nThis is a demo that shows mean-shift based tracking using Transparent API\n" + "You select a color objects such as your face and it tracks it.\n" + "This reads from video camera (0 by default, or the camera number the user enters\n" + "Usage: \n" + " ./camshiftdemo [camera number]\n"; + + std::cout << "\n\nHot keys: \n" + "\tESC - quit the program\n" + "\tc - stop the tracking\n" + "\tb - switch to/from backprojection view\n" + "\th - show/hide object histogram\n" + "\tp - pause video\n" + "To initialize tracking, select the object with mouse\n"; +} + +int main(int argc, const char** argv) +{ + help(); + + cv::VideoCapture cap; + cv::Rect trackWindow; + int hsize = 16; + float hranges[2] = { 0, 180 }; + const float * phranges = hranges; + + const char * const keys = { "{@camera_number| 0 | camera number}" }; + cv::CommandLineParser parser(argc, argv, keys); + int camNum = parser.get(0); + + cap.open(camNum); + + if (!cap.isOpened()) + { + help(); + std::cout << "***Could not initialize capturing...***\n"; + std::cout << "Current parameter's value: \n"; + parser.printMessage(); + + return EXIT_FAILURE; + } + + cv::namedWindow("Histogram", cv::WINDOW_NORMAL); + cv::namedWindow("CamShift Demo", cv::WINDOW_NORMAL); + cv::setMouseCallback("CamShift Demo", onMouse, NULL); + cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256, NULL); + cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256, NULL); + cv::createTrackbar("Smin", "CamShift Demo", &smin, 256, NULL); + + cv::Mat frame, hsv, hue, mask, hist, histimg = cv::Mat::zeros(200, 320, CV_8UC3), backproj; + bool paused = false; + + for ( ; ; ) + { + if (!paused) + { + cap >> frame; + if (frame.empty()) + break; + } + + frame.copyTo(image); + + if (!paused) + { + cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV); + + if (trackObject) + { + int _vmin = vmin, _vmax = vmax; + + cv::inRange(hsv, cv::Scalar(0, smin, std::min(_vmin, _vmax)), + cv::Scalar(180, 256, std::max(_vmin, _vmax)), mask); + + int ch[2] = { 0, 0 }; + hue.create(hsv.size(), hsv.depth()); + cv::mixChannels(&hsv, 1, &hue, 1, ch, 1); + + if (trackObject < 0) + { + cv::Mat roi(hue, selection), maskroi(mask, selection); + cv::calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); + cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX); + + trackWindow = selection; + trackObject = 1; + + histimg = cv::Scalar::all(0); + int binW = histimg.cols / hsize; + cv::Mat buf (1, hsize, CV_8UC3); + for (int i = 0; i < hsize; i++) + buf.at(i) = cv::Vec3b(cv::saturate_cast(i*180./hsize), 255, 255); + cv::cvtColor(buf, buf, cv::COLOR_HSV2BGR); + + for (int i = 0; i < hsize; i++) + { + int val = cv::saturate_cast(hist.at(i)*histimg.rows/255); + cv::rectangle(histimg, cv::Point(i*binW, histimg.rows), + cv::Point((i+1)*binW, histimg.rows - val), + cv::Scalar(buf.at(i)), -1, 8); + } + } + + cv::calcBackProject(&hue, 1, 0, hist, backproj, &phranges); + backproj &= mask; + cv::RotatedRect trackBox = cv::CamShift(backproj, trackWindow, + cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1)); + if (trackWindow.area() <= 1) + { + int cols = backproj.cols, rows = backproj.rows, r = (std::min(cols, rows) + 5)/6; + trackWindow = cv::Rect(trackWindow.x - r, trackWindow.y - r, + trackWindow.x + r, trackWindow.y + r) & + cv::Rect(0, 0, cols, rows); + } + + if (backprojMode) + cv::cvtColor(backproj, image, cv::COLOR_GRAY2BGR); + cv::ellipse(image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA); + } + } + else if (trackObject < 0) + paused = false; + + if (selectObject && selection.width > 0 && selection.height > 0) + { + cv::Mat roi(image, selection); + cv::bitwise_not(roi, roi); + } + + cv::imshow("CamShift Demo", image); + cv::imshow("Histogram", histimg); + + char c = (char)cv::waitKey(10); + if (c == 27) + break; + + switch(c) + { + case 'b': + backprojMode = !backprojMode; + break; + case 'c': + trackObject = 0; + histimg = cv::Scalar::all(0); + break; + case 'h': + showHist = !showHist; + if (!showHist) + cv::destroyWindow("Histogram"); + else + cv::namedWindow("Histogram", cv::WINDOW_AUTOSIZE); + break; + case 'p': + paused = !paused; + break; + default: + break; + } + } + + return EXIT_SUCCESS; +} From c4c913ff131b29aed1db47f3378585213682f729 Mon Sep 17 00:00:00 2001 From: Ilya Lavrenov Date: Sun, 29 Dec 2013 14:36:30 +0400 Subject: [PATCH 2/2] converted CPU-based example to T-API (Mat 2 UMat, etc) --- modules/core/include/opencv2/core/mat.inl.hpp | 6 ++ samples/ocl/CMakeLists.txt | 5 +- samples/tapi/camshift.cpp | 69 ++++++++++++------- 3 files changed, 52 insertions(+), 28 deletions(-) diff --git a/modules/core/include/opencv2/core/mat.inl.hpp b/modules/core/include/opencv2/core/mat.inl.hpp index 9c2f595b6a..f02bf9d446 100644 --- a/modules/core/include/opencv2/core/mat.inl.hpp +++ b/modules/core/include/opencv2/core/mat.inl.hpp @@ -267,6 +267,12 @@ inline _InputOutputArray::_InputOutputArray(const Mat& m) inline _InputOutputArray::_InputOutputArray(const std::vector& vec) { init(FIXED_SIZE + STD_VECTOR_MAT + ACCESS_RW, &vec); } +inline _InputOutputArray::_InputOutputArray(const UMat& m) +{ init(FIXED_TYPE + FIXED_SIZE + UMAT + ACCESS_RW, &m); } + +inline _InputOutputArray::_InputOutputArray(const std::vector& vec) +{ init(FIXED_SIZE + STD_VECTOR_UMAT + ACCESS_RW, &vec); } + inline _InputOutputArray::_InputOutputArray(const cuda::GpuMat& d_mat) { init(FIXED_TYPE + FIXED_SIZE + GPU_MAT + ACCESS_RW, &d_mat); } diff --git a/samples/ocl/CMakeLists.txt b/samples/ocl/CMakeLists.txt index 9344fb08ca..41c8612dae 100644 --- a/samples/ocl/CMakeLists.txt +++ b/samples/ocl/CMakeLists.txt @@ -1,6 +1,7 @@ -SET(OPENCV_OCL_SAMPLES_REQUIRED_DEPS opencv_core opencv_imgproc opencv_highgui +SET(OPENCV_OCL_SAMPLES_REQUIRED_DEPS opencv_core opencv_flann opencv_imgproc opencv_highgui opencv_ml opencv_video opencv_objdetect opencv_features2d - opencv_ocl opencv_nonfree opencv_bioinspired) + opencv_calib3d opencv_legacy opencv_contrib opencv_ocl + opencv_nonfree opencv_bioinspired) ocv_check_dependencies(${OPENCV_OCL_SAMPLES_REQUIRED_DEPS}) diff --git a/samples/tapi/camshift.cpp b/samples/tapi/camshift.cpp index d6e353253f..22c65bf698 100644 --- a/samples/tapi/camshift.cpp +++ b/samples/tapi/camshift.cpp @@ -1,4 +1,5 @@ #include "opencv2/core/utility.hpp" +#include "opencv2/core/ocl.hpp" #include "opencv2/video/tracking.hpp" #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" @@ -6,17 +7,18 @@ #include #include -static cv::Mat image; +static cv::UMat image; static bool backprojMode = false; static bool selectObject = false; static int trackObject = 0; static bool showHist = true; -static cv::Point origin; static cv::Rect selection; static int vmin = 10, vmax = 256, smin = 30; static void onMouse(int event, int x, int y, int, void*) { + static cv::Point origin; + if (selectObject) { selection.x = std::min(x, origin.x); @@ -27,7 +29,7 @@ static void onMouse(int event, int x, int y, int, void*) selection &= cv::Rect(0, 0, image.cols, image.rows); } - switch(event) + switch (event) { case cv::EVENT_LBUTTONDOWN: origin = cv::Point(x, y); @@ -54,14 +56,15 @@ static void help() std::cout << "\n\nHot keys: \n" "\tESC - quit the program\n" - "\tc - stop the tracking\n" + "\ts - stop the tracking\n" "\tb - switch to/from backprojection view\n" "\th - show/hide object histogram\n" "\tp - pause video\n" + "\tc - use OpenCL or not\n" "To initialize tracking, select the object with mouse\n"; } -int main(int argc, const char** argv) +int main(int argc, const char ** argv) { help(); @@ -69,7 +72,6 @@ int main(int argc, const char** argv) cv::Rect trackWindow; int hsize = 16; float hranges[2] = { 0, 180 }; - const float * phranges = hranges; const char * const keys = { "{@camera_number| 0 | camera number}" }; cv::CommandLineParser parser(argc, argv, keys); @@ -80,6 +82,7 @@ int main(int argc, const char** argv) if (!cap.isOpened()) { help(); + std::cout << "***Could not initialize capturing...***\n"; std::cout << "Current parameter's value: \n"; parser.printMessage(); @@ -89,12 +92,13 @@ int main(int argc, const char** argv) cv::namedWindow("Histogram", cv::WINDOW_NORMAL); cv::namedWindow("CamShift Demo", cv::WINDOW_NORMAL); - cv::setMouseCallback("CamShift Demo", onMouse, NULL); - cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256, NULL); - cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256, NULL); - cv::createTrackbar("Smin", "CamShift Demo", &smin, 256, NULL); + cv::setMouseCallback("CamShift Demo", onMouse); + cv::createTrackbar("Vmin", "CamShift Demo", &vmin, 256); + cv::createTrackbar("Vmax", "CamShift Demo", &vmax, 256); + cv::createTrackbar("Smin", "CamShift Demo", &smin, 256); - cv::Mat frame, hsv, hue, mask, hist, histimg = cv::Mat::zeros(200, 320, CV_8UC3), backproj; + cv::Mat frame, histimg(200, 320, CV_8UC3, cv::Scalar::all(0)); + cv::UMat hsv, hist, hue, mask, backproj; bool paused = false; for ( ; ; ) @@ -119,14 +123,15 @@ int main(int argc, const char** argv) cv::inRange(hsv, cv::Scalar(0, smin, std::min(_vmin, _vmax)), cv::Scalar(180, 256, std::max(_vmin, _vmax)), mask); - int ch[2] = { 0, 0 }; + int fromTo[2] = { 0,0 }; hue.create(hsv.size(), hsv.depth()); - cv::mixChannels(&hsv, 1, &hue, 1, ch, 1); + cv::mixChannels(std::vector(1, hsv), std::vector(1, hue), fromTo, 1); if (trackObject < 0) { - cv::Mat roi(hue, selection), maskroi(mask, selection); - cv::calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges); + cv::UMat roi(hue, selection), maskroi(mask, selection); + cv::calcHist(std::vector(1, roi.getMat(cv::ACCESS_READ)), std::vector(1, 0), + maskroi, hist, std::vector(1, hsize), std::vector(hranges, hranges + 2)); cv::normalize(hist, hist, 0, 255, cv::NORM_MINMAX); trackWindow = selection; @@ -139,17 +144,22 @@ int main(int argc, const char** argv) buf.at(i) = cv::Vec3b(cv::saturate_cast(i*180./hsize), 255, 255); cv::cvtColor(buf, buf, cv::COLOR_HSV2BGR); - for (int i = 0; i < hsize; i++) { - int val = cv::saturate_cast(hist.at(i)*histimg.rows/255); - cv::rectangle(histimg, cv::Point(i*binW, histimg.rows), - cv::Point((i+1)*binW, histimg.rows - val), - cv::Scalar(buf.at(i)), -1, 8); + cv::Mat _hist = hist.getMat(cv::ACCESS_READ); + for (int i = 0; i < hsize; i++) + { + int val = cv::saturate_cast(_hist.at(i)*histimg.rows/255); + cv::rectangle(histimg, cv::Point(i*binW, histimg.rows), + cv::Point((i+1)*binW, histimg.rows - val), + cv::Scalar(buf.at(i)), -1, 8); + } } } - cv::calcBackProject(&hue, 1, 0, hist, backproj, &phranges); - backproj &= mask; + cv::calcBackProject(std::vector(1, hue), std::vector(1, 0), hist, backproj, + std::vector(hranges, hranges + 2), 1.0); + cv::bitwise_and(backproj, mask, backproj); + cv::RotatedRect trackBox = cv::CamShift(backproj, trackWindow, cv::TermCriteria(cv::TermCriteria::EPS | cv::TermCriteria::COUNT, 10, 1)); if (trackWindow.area() <= 1) @@ -162,7 +172,11 @@ int main(int argc, const char** argv) if (backprojMode) cv::cvtColor(backproj, image, cv::COLOR_GRAY2BGR); - cv::ellipse(image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA); + + { + cv::Mat _image = image.getMat(cv::ACCESS_RW); + cv::ellipse(_image, trackBox, cv::Scalar(0, 0, 255), 3, cv::LINE_AA); + } } } else if (trackObject < 0) @@ -170,12 +184,13 @@ int main(int argc, const char** argv) if (selectObject && selection.width > 0 && selection.height > 0) { - cv::Mat roi(image, selection); + cv::UMat roi(image, selection); cv::bitwise_not(roi, roi); } cv::imshow("CamShift Demo", image); - cv::imshow("Histogram", histimg); + if (showHist) + cv::imshow("Histogram", histimg); char c = (char)cv::waitKey(10); if (c == 27) @@ -186,7 +201,7 @@ int main(int argc, const char** argv) case 'b': backprojMode = !backprojMode; break; - case 'c': + case 't': trackObject = 0; histimg = cv::Scalar::all(0); break; @@ -200,6 +215,8 @@ int main(int argc, const char** argv) case 'p': paused = !paused; break; + case 'c': + cv::ocl::setUseOpenCL(!cv::ocl::useOpenCL()); default: break; }