From 0e9a865bbf809e6b877d80fc0cf2cb7500d141a8 Mon Sep 17 00:00:00 2001 From: Vishal Chiluka Date: Wed, 15 May 2019 15:21:40 +0530 Subject: [PATCH 1/2] Moved NVIDIA_Optical_Flow sample app to opencv_contrib Description: Moved NVIDIA_Optical_flow sample app and comparison app to opencv_contrib branch. Added CUDA_CUDA_LIBRARY in CMakeLists.txt for resolving linker errors. --- CMakeLists.txt | 2 +- samples/gpu/optical_flow.cpp | 240 ----------------------------------- 2 files changed, 1 insertion(+), 241 deletions(-) delete mode 100644 samples/gpu/optical_flow.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 957c563d18..a296121bd5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -919,7 +919,7 @@ unset(_hal_includes) # Add CUDA libraries (needed for apps/tools, samples) # ---------------------------------------------------------------------------- if(HAVE_CUDA) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_npp_LIBRARY}) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_npp_LIBRARY}) if(HAVE_CUBLAS) set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY}) endif() diff --git a/samples/gpu/optical_flow.cpp b/samples/gpu/optical_flow.cpp deleted file mode 100644 index b1b3c8de1e..0000000000 --- a/samples/gpu/optical_flow.cpp +++ /dev/null @@ -1,240 +0,0 @@ -#include -#include - -#include "opencv2/core.hpp" -#include -#include "opencv2/highgui.hpp" -#include "opencv2/cudaoptflow.hpp" -#include "opencv2/cudaarithm.hpp" - -using namespace std; -using namespace cv; -using namespace cv::cuda; - -inline bool isFlowCorrect(Point2f u) -{ - return !cvIsNaN(u.x) && !cvIsNaN(u.y) && fabs(u.x) < 1e9 && fabs(u.y) < 1e9; -} - -static Vec3b computeColor(float fx, float fy) -{ - static bool first = true; - - // relative lengths of color transitions: - // these are chosen based on perceptual similarity - // (e.g. one can distinguish more shades between red and yellow - // than between yellow and green) - const int RY = 15; - const int YG = 6; - const int GC = 4; - const int CB = 11; - const int BM = 13; - const int MR = 6; - const int NCOLS = RY + YG + GC + CB + BM + MR; - static Vec3i colorWheel[NCOLS]; - - if (first) - { - int k = 0; - - for (int i = 0; i < RY; ++i, ++k) - colorWheel[k] = Vec3i(255, 255 * i / RY, 0); - - for (int i = 0; i < YG; ++i, ++k) - colorWheel[k] = Vec3i(255 - 255 * i / YG, 255, 0); - - for (int i = 0; i < GC; ++i, ++k) - colorWheel[k] = Vec3i(0, 255, 255 * i / GC); - - for (int i = 0; i < CB; ++i, ++k) - colorWheel[k] = Vec3i(0, 255 - 255 * i / CB, 255); - - for (int i = 0; i < BM; ++i, ++k) - colorWheel[k] = Vec3i(255 * i / BM, 0, 255); - - for (int i = 0; i < MR; ++i, ++k) - colorWheel[k] = Vec3i(255, 0, 255 - 255 * i / MR); - - first = false; - } - - const float rad = sqrt(fx * fx + fy * fy); - const float a = atan2(-fy, -fx) / (float) CV_PI; - - const float fk = (a + 1.0f) / 2.0f * (NCOLS - 1); - const int k0 = static_cast(fk); - const int k1 = (k0 + 1) % NCOLS; - const float f = fk - k0; - - Vec3b pix; - - for (int b = 0; b < 3; b++) - { - const float col0 = colorWheel[k0][b] / 255.0f; - const float col1 = colorWheel[k1][b] / 255.0f; - - float col = (1 - f) * col0 + f * col1; - - if (rad <= 1) - col = 1 - rad * (1 - col); // increase saturation with radius - else - col *= .75; // out of range - - pix[2 - b] = static_cast(255.0 * col); - } - - return pix; -} - -static void drawOpticalFlow(const Mat_& flowx, const Mat_& flowy, Mat& dst, float maxmotion = -1) -{ - dst.create(flowx.size(), CV_8UC3); - dst.setTo(Scalar::all(0)); - - // determine motion range: - float maxrad = maxmotion; - - if (maxmotion <= 0) - { - maxrad = 1; - for (int y = 0; y < flowx.rows; ++y) - { - for (int x = 0; x < flowx.cols; ++x) - { - Point2f u(flowx(y, x), flowy(y, x)); - - if (!isFlowCorrect(u)) - continue; - - maxrad = max(maxrad, sqrt(u.x * u.x + u.y * u.y)); - } - } - } - - for (int y = 0; y < flowx.rows; ++y) - { - for (int x = 0; x < flowx.cols; ++x) - { - Point2f u(flowx(y, x), flowy(y, x)); - - if (isFlowCorrect(u)) - dst.at(y, x) = computeColor(u.x / maxrad, u.y / maxrad); - } - } -} - -static void showFlow(const char* name, const GpuMat& d_flow) -{ - GpuMat planes[2]; - cuda::split(d_flow, planes); - - Mat flowx(planes[0]); - Mat flowy(planes[1]); - - Mat out; - drawOpticalFlow(flowx, flowy, out, 10); - - imshow(name, out); -} - -int main(int argc, const char* argv[]) -{ - string filename1, filename2; - if (argc < 3) - { - cerr << "Usage : " << argv[0] << " " << endl; - filename1 = "../data/basketball1.png"; - filename2 = "../data/basketball2.png"; - } - else - { - filename1 = argv[1]; - filename2 = argv[2]; - } - - Mat frame0 = imread(filename1, IMREAD_GRAYSCALE); - Mat frame1 = imread(filename2, IMREAD_GRAYSCALE); - - if (frame0.empty()) - { - cerr << "Can't open image [" << filename1 << "]" << endl; - return -1; - } - if (frame1.empty()) - { - cerr << "Can't open image [" << filename2 << "]" << endl; - return -1; - } - - if (frame1.size() != frame0.size()) - { - cerr << "Images should be of equal sizes" << endl; - return -1; - } - - GpuMat d_frame0(frame0); - GpuMat d_frame1(frame1); - - GpuMat d_flow(frame0.size(), CV_32FC2); - - Ptr brox = cuda::BroxOpticalFlow::create(0.197f, 50.0f, 0.8f, 10, 77, 10); - Ptr lk = cuda::DensePyrLKOpticalFlow::create(Size(7, 7)); - Ptr farn = cuda::FarnebackOpticalFlow::create(); - Ptr tvl1 = cuda::OpticalFlowDual_TVL1::create(); - - { - GpuMat d_frame0f; - GpuMat d_frame1f; - - d_frame0.convertTo(d_frame0f, CV_32F, 1.0 / 255.0); - d_frame1.convertTo(d_frame1f, CV_32F, 1.0 / 255.0); - - const int64 start = getTickCount(); - - brox->calc(d_frame0f, d_frame1f, d_flow); - - const double timeSec = (getTickCount() - start) / getTickFrequency(); - cout << "Brox : " << timeSec << " sec" << endl; - - showFlow("Brox", d_flow); - } - - { - const int64 start = getTickCount(); - - lk->calc(d_frame0, d_frame1, d_flow); - - const double timeSec = (getTickCount() - start) / getTickFrequency(); - cout << "LK : " << timeSec << " sec" << endl; - - showFlow("LK", d_flow); - } - - { - const int64 start = getTickCount(); - - farn->calc(d_frame0, d_frame1, d_flow); - - const double timeSec = (getTickCount() - start) / getTickFrequency(); - cout << "Farn : " << timeSec << " sec" << endl; - - showFlow("Farn", d_flow); - } - - { - const int64 start = getTickCount(); - - tvl1->calc(d_frame0, d_frame1, d_flow); - - const double timeSec = (getTickCount() - start) / getTickFrequency(); - cout << "TVL1 : " << timeSec << " sec" << endl; - - showFlow("TVL1", d_flow); - } - - imshow("Frame 0", frame0); - imshow("Frame 1", frame1); - waitKey(); - - return 0; -} From 0fc584961c80e4e739d6b1c777aa81e0f76def88 Mon Sep 17 00:00:00 2001 From: Alexander Alekhin Date: Fri, 5 Jul 2019 23:10:41 +0000 Subject: [PATCH 2/2] cmake: workaround to fix link issues with stubs/libcuda.so.1 --- CMakeLists.txt | 24 ------------------ cmake/OpenCVDetectCUDA.cmake | 49 ++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+), 24 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a296121bd5..bbb823b971 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -915,30 +915,6 @@ configure_file("${OpenCV_SOURCE_DIR}/cmake/templates/custom_hal.hpp.in" "${CMAKE unset(_hal_includes) -# ---------------------------------------------------------------------------- -# Add CUDA libraries (needed for apps/tools, samples) -# ---------------------------------------------------------------------------- -if(HAVE_CUDA) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_npp_LIBRARY}) - if(HAVE_CUBLAS) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY}) - endif() - if(HAVE_CUDNN) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES}) - endif() - if(HAVE_CUFFT) - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY}) - endif() - foreach(p ${CUDA_LIBS_PATH}) - if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM") - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}") - else() - set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p}) - endif() - endforeach() -endif() - - # ---------------------------------------------------------------------------- # Code trace support # ---------------------------------------------------------------------------- diff --git a/cmake/OpenCVDetectCUDA.cmake b/cmake/OpenCVDetectCUDA.cmake index 35c5409fc1..4deb178f2f 100644 --- a/cmake/OpenCVDetectCUDA.cmake +++ b/cmake/OpenCVDetectCUDA.cmake @@ -337,3 +337,52 @@ if(HAVE_CUDA) ocv_convert_to_lib_name(CUDA_cufft_LIBRARY ${CUDA_cufft_LIBRARY}) endif() endif() + + +# ---------------------------------------------------------------------------- +# Add CUDA libraries (needed for apps/tools, samples) +# ---------------------------------------------------------------------------- +if(HAVE_CUDA) + # details: https://github.com/NVIDIA/nvidia-docker/issues/775 + if(" ${CUDA_CUDA_LIBRARY}" MATCHES "/stubs/libcuda.so" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND) + set(CUDA_STUB_ENABLED_LINK_WORKAROUND 1) + if(EXISTS "${CUDA_CUDA_LIBRARY}" AND NOT OPENCV_SKIP_CUDA_STUB_WORKAROUND_RPATH_LINK) + set(CUDA_STUB_TARGET_PATH "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/") + execute_process(COMMAND ${CMAKE_COMMAND} -E create_symlink "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1" + RESULT_VARIABLE CUDA_STUB_SYMLINK_RESULT) + if(NOT CUDA_STUB_SYMLINK_RESULT EQUAL 0) + execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${CUDA_CUDA_LIBRARY}" "${CUDA_STUB_TARGET_PATH}/libcuda.so.1" + RESULT_VARIABLE CUDA_STUB_COPY_RESULT) + if(NOT CUDA_STUB_COPY_RESULT EQUAL 0) + set(CUDA_STUB_ENABLED_LINK_WORKAROUND 0) + endif() + endif() + if(CUDA_STUB_ENABLED_LINK_WORKAROUND) + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,-rpath-link,\"${CUDA_STUB_TARGET_PATH}\"") + endif() + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -Wl,--allow-shlib-undefined") + endif() + if(NOT CUDA_STUB_ENABLED_LINK_WORKAROUND) + message(WARNING "CUDA: workaround for stubs/libcuda.so.1 is not applied") + endif() + endif() + + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_LIBRARIES} ${CUDA_CUDA_LIBRARY} ${CUDA_npp_LIBRARY}) + if(HAVE_CUBLAS) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cublas_LIBRARY}) + endif() + if(HAVE_CUDNN) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDNN_LIBRARIES}) + endif() + if(HAVE_CUFFT) + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CUDA_cufft_LIBRARY}) + endif() + foreach(p ${CUDA_LIBS_PATH}) + if(MSVC AND CMAKE_GENERATOR MATCHES "Ninja|JOM") + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}"${p}") + else() + set(OPENCV_LINKER_LIBS ${OPENCV_LINKER_LIBS} ${CMAKE_LIBRARY_PATH_FLAG}${p}) + endif() + endforeach() +endif()