OpenCV 3.2.0 windows,OpenCL 在 C++ 中显示设备但在 python 中不显示

OpenCV 3.2.0 windows, OpenCL shows devices in C++ but not in python

我正在使用 2 个示例脚本来检查 python 3.6 是否可以在 windows 上使用 Opencv 的 OpenCL 功能。我尝试 运行 示例中提供的几个与 CAMSHIFT 相关的示例,并检查我是否有 OpenCL。

我很想知道为什么 python 显示我没有 opencl 而带有 VS 的 C++ 显示我有启用 opencl 的设备

系统信息:

Opencv 3.2.0 使用 Opencl 从源代码构建并添加了 python 和 numpy 库

Python 3.6 用于 windows 64 位

Visual Studio 2015 社区版

Numpy 使用

pip install numpy-1.12.0-cp36-none-win_amd64.whl

Python 3.6 使用

python 的 Opnecv
pip install opencv_opencv_python-3.2.0-cp36-cp36m-win_amd64.whl

我运行 VS2015 上提供的以下示例(添加了一个小代码块以检查启用 opencl 的设备是否可用)

#include <opencv2/core/utility.hpp>
#include "opencv2/video/tracking.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/videoio.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/core/ocl.hpp"
#include <stdio.h>
#include <string.h>

#include <iostream>
#include <ctype.h>

using namespace cv;
using namespace std;

Mat image;

bool backprojMode = false;
bool selectObject = false;
int trackObject = 0;
bool showHist = true;
Point origin;
Rect selection;
int vmin = 10, vmax = 256, smin = 30;

// User draws box around object to track. This triggers CAMShift to start tracking
static void onMouse(int event, int x, int y, int, void*)
{
    if (selectObject)
    {
        selection.x = MIN(x, origin.x);
        selection.y = MIN(y, origin.y);
        selection.width = std::abs(x - origin.x);
        selection.height = std::abs(y - origin.y);

        selection &= Rect(0, 0, image.cols, image.rows);
    }

    switch (event)
    {
    case EVENT_LBUTTONDOWN:
        origin = Point(x, y);
        selection = Rect(x, y, 0, 0);
        selectObject = true;
        break;
    case EVENT_LBUTTONUP:
        selectObject = false;
        if (selection.width > 0 && selection.height > 0)
            trackObject = -1;   // Set up CAMShift properties in main() loop
        break;
    }
}

string hot_keys =
"\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";

static void help()
{
    cout << "\nThis is a demo that shows mean-shift based tracking\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";
    cout << hot_keys;
}

const char* keys =
{
    "{help h | | show help message}{@camera_number| 0 | camera number}"
};

int main(int argc, const char** argv)
{   
    // Start of OpenCL Check
    if (!cv::ocl::haveOpenCL()) { printf("Computer Vision library is not available...\n"); }
    else {
        //printf << "\nOpenCL IS AVAILABLE!\n" << endl;
        cv::ocl::setUseOpenCL(true);
        cv::ocl::Context context;
        if (!context.create(cv::ocl::Device::TYPE_ALL)) { printf("Failed creating the context...\n"); }
        else { printf("Successfully created context!\n"); }

        printf("Connected Device(s): %zd \n", context.ndevices()); //This bit provides an overview of the OpenCL devices you have in your computer
        for (int i = 0; i < context.ndevices(); i++) {
            cv::ocl::Device device = context.device(i);
            cout << "name:              " << device.name() << endl;
            cout << "available:         " << device.available() << endl;
            cout << "imageSupport:      " << device.imageSupport() << endl;
            cout << "OpenCL_C_Version:  " << device.OpenCL_C_Version() << endl;
            cout << endl;
        }
    }
    // END of OpenCL Check
    VideoCapture cap;
    Rect trackWindow;
    int hsize = 16;
    float hranges[] = { 0,180 };
    const float* phranges = hranges;
    CommandLineParser parser(argc, argv, keys);
    if (parser.has("help"))
    {
        help();
        return 0;
    }
    int camNum = parser.get<int>(0);
    cap.open(camNum);

    if (!cap.isOpened())
    {
        help();
        cout << "***Could not initialize capturing...***\n";
        cout << "Current parameter's value: \n";
        parser.printMessage();
        return -1;
    }
    cout << hot_keys;
    namedWindow("Histogram", 0);
    namedWindow("CamShift Demo", 0);
    setMouseCallback("CamShift Demo", onMouse, 0);
    createTrackbar("Vmin", "CamShift Demo", &vmin, 256, 0);
    createTrackbar("Vmax", "CamShift Demo", &vmax, 256, 0);
    createTrackbar("Smin", "CamShift Demo", &smin, 256, 0);

    Mat frame, hsv, hue, mask, hist, histimg = Mat::zeros(200, 320, CV_8UC3), backproj;
    bool paused = false;

    for (;;)
    {
        if (!paused)
        {
            cap >> frame;
            if (frame.empty())
                break;
        }

        frame.copyTo(image);

        if (!paused)
        {
            cvtColor(image, hsv, COLOR_BGR2HSV);

            if (trackObject)
            {
                int _vmin = vmin, _vmax = vmax;

                inRange(hsv, Scalar(0, smin, MIN(_vmin, _vmax)),
                    Scalar(180, 256, MAX(_vmin, _vmax)), mask);
                int ch[] = { 0, 0 };
                hue.create(hsv.size(), hsv.depth());
                mixChannels(&hsv, 1, &hue, 1, ch, 1);

                if (trackObject < 0)
                {
                    // Object has been selected by user, set up CAMShift search properties once
                    Mat roi(hue, selection), maskroi(mask, selection);
                    calcHist(&roi, 1, 0, maskroi, hist, 1, &hsize, &phranges);
                    normalize(hist, hist, 0, 255, NORM_MINMAX);

                    trackWindow = selection;
                    trackObject = 1; // Don't set up again, unless user selects new ROI

                    histimg = Scalar::all(0);
                    int binW = histimg.cols / hsize;
                    Mat buf(1, hsize, CV_8UC3);
                    for (int i = 0; i < hsize; i++)
                        buf.at<Vec3b>(i) = Vec3b(saturate_cast<uchar>(i*180. / hsize), 255, 255);
                    cvtColor(buf, buf, COLOR_HSV2BGR);

                    for (int i = 0; i < hsize; i++)
                    {
                        int val = saturate_cast<int>(hist.at<float>(i)*histimg.rows / 255);
                        rectangle(histimg, Point(i*binW, histimg.rows),
                            Point((i + 1)*binW, histimg.rows - val),
                            Scalar(buf.at<Vec3b>(i)), -1, 8);
                    }
                }

                // Perform CAMShift
                calcBackProject(&hue, 1, 0, hist, backproj, &phranges);
                backproj &= mask;
                RotatedRect trackBox = CamShift(backproj, trackWindow,
                    TermCriteria(TermCriteria::EPS | TermCriteria::COUNT, 10, 1));
                if (trackWindow.area() <= 1)
                {
                    int cols = backproj.cols, rows = backproj.rows, r = (MIN(cols, rows) + 5) / 6;
                    trackWindow = Rect(trackWindow.x - r, trackWindow.y - r,
                        trackWindow.x + r, trackWindow.y + r) &
                        Rect(0, 0, cols, rows);
                }

                if (backprojMode)
                    cvtColor(backproj, image, COLOR_GRAY2BGR);
                ellipse(image, trackBox, Scalar(0, 0, 255), 3, LINE_AA);
            }
        }
        else if (trackObject < 0)
            paused = false;

        if (selectObject && selection.width > 0 && selection.height > 0)
        {
            Mat roi(image, selection);
            bitwise_not(roi, roi);
        }

        imshow("CamShift Demo", image);
        imshow("Histogram", histimg);

        char c = (char)waitKey(10);
        if (c == 27)
            break;
        switch (c)
        {
        case 'b':
            backprojMode = !backprojMode;
            break;
        case 'c':
            trackObject = 0;
            histimg = Scalar::all(0);
            break;
        case 'h':
            showHist = !showHist;
            if (!showHist)
                destroyWindow("Histogram");
            else
                namedWindow("Histogram", 1);
            break;
        case 'p':
            paused = !paused;
            break;
        default:
            ;
        }
    }

    return 0;
}

我得到的输出结果如下:

然后我 运行 python 中可用的相同 Camshift 示例(添加了几行以检查 opencl 是否可用)

#!/usr/bin/env python

'''
Camshift tracker
================

This is a demo that shows mean-shift based tracking
You select a color objects such as your face and it tracks it.
This reads from video camera (0 by default, or the camera number the user enters)

http://www.robinhewitt.com/research/track/camshift.html

Usage:
------
    camshift.py [<video source>]

    To initialize tracking, select the object with mouse

Keys:
-----
    ESC   - exit
    b     - toggle back-projected probability visualization
'''

# Python 2/3 compatibility
from __future__ import print_function
import sys
PY3 = sys.version_info[0] == 3

if PY3:
    xrange = range

import numpy as np
import cv2

# local module
import video
from video import presets


class App(object):
    def __init__(self, video_src):
        self.cam = video.create_capture(video_src, presets['cube'])
        ret, self.frame = self.cam.read()
        cv2.namedWindow('camshift')
        cv2.setMouseCallback('camshift', self.onmouse)

        self.selection = None
        self.drag_start = None
        self.show_backproj = False
        self.track_window = None

    def onmouse(self, event, x, y, flags, param):
        if event == cv2.EVENT_LBUTTONDOWN:
            self.drag_start = (x, y)
            self.track_window = None
        if self.drag_start:
            xmin = min(x, self.drag_start[0])
            ymin = min(y, self.drag_start[1])
            xmax = max(x, self.drag_start[0])
            ymax = max(y, self.drag_start[1])
            self.selection = (xmin, ymin, xmax, ymax)
        if event == cv2.EVENT_LBUTTONUP:
            self.drag_start = None
            self.track_window = (xmin, ymin, xmax - xmin, ymax - ymin)

    def show_hist(self):
        bin_count = self.hist.shape[0]
        bin_w = 24
        img = np.zeros((256, bin_count*bin_w, 3), np.uint8)
        for i in xrange(bin_count):
            h = int(self.hist[i])
            cv2.rectangle(img, (i*bin_w+2, 255), ((i+1)*bin_w-2, 255-h), (int(180.0*i/bin_count), 255, 255), -1)
        img = cv2.cvtColor(img, cv2.COLOR_HSV2BGR)
        cv2.imshow('hist', img)

    def run(self):
        #Check to see if device has opencl
        print("---------------------")
        if (cv2.ocl.haveOpenCL()):
            print("OpenCL available")
        else:
            print("OpenCL not available")
        print("---------------------")

        while True:
            ret, self.frame = self.cam.read()
            vis = self.frame.copy()
            hsv = cv2.cvtColor(self.frame, cv2.COLOR_BGR2HSV)
            mask = cv2.inRange(hsv, np.array((0., 60., 32.)), np.array((180., 255., 255.)))

            if self.selection:
                x0, y0, x1, y1 = self.selection
                hsv_roi = hsv[y0:y1, x0:x1]
                mask_roi = mask[y0:y1, x0:x1]
                hist = cv2.calcHist( [hsv_roi], [0], mask_roi, [16], [0, 180] )
                cv2.normalize(hist, hist, 0, 255, cv2.NORM_MINMAX)
                self.hist = hist.reshape(-1)
                self.show_hist()

                vis_roi = vis[y0:y1, x0:x1]
                cv2.bitwise_not(vis_roi, vis_roi)
                vis[mask == 0] = 0

            if self.track_window and self.track_window[2] > 0 and self.track_window[3] > 0:
                self.selection = None
                prob = cv2.calcBackProject([hsv], [0], self.hist, [0, 180], 1)
                prob &= mask
                term_crit = ( cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 1 )
                track_box, self.track_window = cv2.CamShift(prob, self.track_window, term_crit)

                if self.show_backproj:
                    vis[:] = prob[...,np.newaxis]
                try:
                    cv2.ellipse(vis, track_box, (0, 0, 255), 2)
                except:
                    print(track_box)

            cv2.imshow('camshift', vis)

            ch = cv2.waitKey(5)
            if ch == 27:
                break
            if ch == ord('b'):
                self.show_backproj = not self.show_backproj
        cv2.destroyAllWindows()


if __name__ == '__main__':
    import sys
    try:
        video_src = sys.argv[1]
    except:
        video_src = 0
    print(__doc__)
    App(video_src).run()

得到的结果如下:

    General configuration for OpenCV 3.2.0 =====================================

      Platform:
        Timestamp:                   2016-12-23T19:22:45Z
        Host:                        Windows 10.0.14393 AMD64
        CMake:                       3.6.3
        CMake generator:             Visual Studio 14 2015 Win64
        CMake build tool:            C:/Program Files (x86)/MSBuild/14.0/bin/MSBuild.exe
        MSVC:                        1900

      C/C++:
        Built as dynamic libs?:      YES
        C++ Compiler:                C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe  (ver 19.0.24215.1)
        C++ flags (Release):         /DWIN32 /D_WINDOWS /W4 /GR /EHa  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi  /wd4251 /wd4324 /wd4275 /wd4589 /MP12  /MD /O2 /Ob2 /DNDEBUG  /Zi
        C++ flags (Debug):           /DWIN32 /D_WINDOWS /W4 /GR /EHa  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi  /wd4251 /wd4324 /wd4275 /wd4589 /MP12  /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 
        C Compiler:                  C:/Program Files (x86)/Microsoft Visual Studio 14.0/VC/bin/x86_amd64/cl.exe
        C flags (Release):           /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi    /MP12  /MD /O2 /Ob2 /DNDEBUG  /Zi
        C flags (Debug):             /DWIN32 /D_WINDOWS /W3  /D _CRT_SECURE_NO_DEPRECATE /D _CRT_NONSTDC_NO_DEPRECATE /D _SCL_SECURE_NO_WARNINGS /Gy /bigobj /Oi    /MP12  /D_DEBUG /MDd /Zi /Ob0 /Od /RTC1 
        Linker flags (Release):      /machine:x64  /INCREMENTAL:NO  /debug
        Linker flags (Debug):        /machine:x64  /debug /INCREMENTAL 
        ccache:                      NO
        Precompiled headers:         YES
        Extra dependencies:          comctl32 gdi32 ole32 setupapi ws2_32 vfw32 glu32 opengl32 C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_core.lib C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_intel_lp64.lib C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_sequential.lib
        3rdparty dependencies:       zlib libjpeg libwebp libpng libtiff libjasper IlmImf

      OpenCV modules:
        To be built:                 core flann imgproc ml photo video imgcodecs shape videoio highgui objdetect superres ts features2d calib3d stitching videostab python3
        Disabled:                    python2 world
        Disabled by dependency:      -
        Unavailable:                 cudaarithm cudabgsegm cudacodec cudafeatures2d cudafilters cudaimgproc cudalegacy cudaobjdetect cudaoptflow cudastereo cudawarping cudev java viz

      Windows RT support:            NO

      GUI: 
        QT:                          NO
        Win32 UI:                    YES
        OpenGL support:              YES (glu32 opengl32)
        VTK support:                 NO

      Media I/O: 
        ZLib:                        build (ver 1.2.8)
        JPEG:                        build (ver 90)
        WEBP:                        build (ver 0.3.1)
        PNG:                         build (ver 1.6.24)
        TIFF:                        build (ver 42 - 4.0.2)
        JPEG 2000:                   build (ver 1.900.1)
        OpenEXR:                     build (ver 1.7.1)
        GDAL:                        NO
        GDCM:                        NO

      Video I/O:
        Video for Windows:           YES
        DC1394 1.x:                  NO
        DC1394 2.x:                  NO
        FFMPEG:                      YES (prebuilt binaries)
          avcodec:                   YES (ver 57.64.101)
          avformat:                  YES (ver 57.56.100)
          avutil:                    YES (ver 55.34.100)
          swscale:                   YES (ver 4.2.100)
          avresample:                YES (ver 3.1.0)
        GStreamer:                   NO
        OpenNI:                      NO
        OpenNI PrimeSensor Modules:  NO
        OpenNI2:                     NO
        PvAPI:                       NO
        GigEVisionSDK:               NO
        DirectShow:                  YES
        Media Foundation:            NO
        XIMEA:                       NO
        Intel PerC:                  NO

      Parallel framework:            Concurrency

      Other third-party libraries:
        Use IPP:                     9.0.1 [9.0.1]
             at:                     D:/Build/OpenCV/opencv-3.2.0-vc14-x64/3rdparty/ippicv/ippicv_win
        Use IPP Async:               NO
        Use Lapack:                  YES (C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_core.lib C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_intel_lp64.lib C:/Program Files (x86)/IntelSWTools/compilers_and_libraries/windows/mkl/lib/intel64/mkl_sequential.lib)
        Use Eigen:                   NO
        Use Cuda:                    NO
        Use OpenCL:                  NO
        Use OpenVX:                  NO
        Use custom HAL:              NO

      Python 2:
        Interpreter:                 X:/Python27-x64/python.exe (ver 2.7.13)

      Python 3:
        Interpreter:                 X:/Python36/python.exe (ver 3.6)
        Libraries:                   X:/Python36/libs/Python36.lib (ver 3.6.0)
        numpy:                       X:/Python36/lib/site-packages/numpy/core/include (ver 1.11.3)
        packages path:               X:/Python36/Lib/site-packages

      Python (for build):            X:/Python27-x64/python.exe

      Java:
        ant:                         NO
        JNI:                         NO
        Java wrappers:               NO
        Java tests:                  NO

      Matlab:                        NO

      Documentation:
        Doxygen:                     NO

      Tests and samples:
        Tests:                       YES
        Performance tests:           YES
        C/C++ Examples:              NO

      Install path:                  D:/Build/OpenCV/opencv-3.2.0-vc14-x64/install

      cvconfig.h is in:              D:/Build/OpenCV/opencv-3.2.0-vc14-x64

试试这个:

import cv2        

print(cv2.ocl.haveOpenCL())
cv2.ocl.setUseOpenCL(True)
print(cv2.ocl.useOpenCL())    
print(cv2.ocl.haveAmdBlas())
print(cv2.ocl.haveAmdFft())

输出:

True # Have OpenCL
True # Use OpenCL
False
False

就我而言,我没有 AMD-BLAS、AMD-FTT

我解决了这个问题,原来我使用的 opencv_opencv_python-3.2.0-cp36-cp36m-win_amd64.whl 文件不是用 OpenCL 构建的,我只需要替换所有python 站点包文件夹中的 dll 文件以及来自 opencv build 文件夹的 .pyd 和 dll 文件。