Closed auscompgeek closed 4 years ago
There's https://github.com/matze/pkgconfig to help with finding the correct include dir, and opencv2/core/version.hpp defines CV_VERSION_{MAJOR,MINOR,REVISION}
, which should be useful. This might not be as difficult as I expected.
Darn. cscore itself doesn't support OpenCV 4.
cscore_src/cscore/src/main/native/cpp/Frame.cpp: In member function ‘cs::Image* cs::Frame::ConvertBGRToMJPEG(cs::Image*, int)’:
cscore_src/cscore/src/main/native/cpp/Frame.cpp:400:41: error: ‘CV_IMWRITE_JPEG_QUALITY’ was not declared in this scope
m_impl->compressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
^~~~~~~~~~~~~~~~~~~~~~~
cscore_src/cscore/src/main/native/cpp/Frame.cpp: In member function ‘cs::Image* cs::Frame::ConvertGrayToMJPEG(cs::Image*, int)’:
cscore_src/cscore/src/main/native/cpp/Frame.cpp:431:41: error: ‘CV_IMWRITE_JPEG_QUALITY’ was not declared in this scope
m_impl->compressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
^~~~~~~~~~~~~~~~~~~~~~~
cscore in allwpilib supports now opencv4.
I build opencv and allwpilib from source. Then I link
ln -fs ~/allwpilib/wpiutil/ ~/robotpy-cscore/cscore_src/wpiutil
ln -fs ~/allwpilib/cscore/ ~/robotpy-cscore/cscore_src/cscore
and finally
python3 setup.y build
but #include <opencv2/opencv.hpp> in src/_cscore.cpp is not found.
You'll have to query pkg-config for the OpenCV include dir. See above for a package to help with that.
Ok need to change setup.py with
def cpp_flag(compiler):
"""Return the -std=c++[11/14/17] compiler flag.
The c++17 is preferred over c++11 and c++14 (when it is available).
"""
if has_flag(compiler, "-std=c++17"):
return "-std=c++17"
elif has_flag(compiler, "-std=c++14"):
return "-std=c++14"
elif has_flag(compiler, "-std=c++11"):
return "-std=c++11"
else:
raise RuntimeError(
"Unsupported compiler -- at least C++11 support " "is needed!"
)
and
include_dirs=[
"pybind11/include",
"cscore_src/cscore/src/main/native/include",
"cscore_src/cscore/src/main/native/cpp",
"cscore_src/wpiutil/src/main/native/include",
"cscore_src/wpiutil/src/main/native/libuv/include",
"/usr/local/include/opencv4",
get_numpy_include(),
],
note: libuv needs to be changed also, not just adding opencv4 include folder
and now we need to fix ndarray_converter.cpp
and ndarray_converter.h
for invalid conversion from ‘int’ to ‘cv::AccessFlag’
And if you want to work with pkgconfig for opencv you need to compile opencv with -D OPENCV_GENERATE_PKGCONFIG=ON
so it creates the opencv4.pc, but with modified setup.py as above, that is not needed.
patch ndarray_converter.cpp
with (int accessFlags
to AccessFlag accessFlags
)
105c105
< UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, int flags, UMatUsageFlags usageFlags) const
---
> UMatData* allocate(int dims0, const int* sizes, int type, void* data, size_t* step, AccessFlag flags, UMatUsageFlags usageFlags) const
134c134
< bool allocate(UMatData* u, int accessFlags, UMatUsageFlags usageFlags) const
---
> bool allocate(UMatData* u, AccessFlag accessFlags, UMatUsageFlags usageFlags) const
I'm surprised that's the only change to the ndarray_converter.cpp
script, are you sure OpenCV 4 doesn't have more changes? After all, the bulk of that was extracted from the OpenCV source code.
Adding /usr/local/include/opencv4
is not a good idea. What if it's installed via a system package? Using pkg-config makes a lot more sense to me.
However, an open question for me is whether we should migrate this to robotpy-build assuming that we migrate everything to binary bindings? In that case, we could utilize pkg-config with robotpy-build directly, and could get rid of the cscore subtree. However, not sure whether the upstream WPILib builds would be able to support python bindings or not.
However, not sure whether the upstream WPILib builds would be able to support python bindings or not.
The upstream builds would be built against the WPILib-packaged OpenCV, so it would definitely not work with the system-installed OpenCV and won't have Python bindings.
I've pushed up what I had in my working tree in my experiments compiling against OpenCV 4: add61ae1f5dcb4ece6e9f4259e30c6da41d372ba
robotpy-cscore is used by https://github.com/wpilibsuite/FRCVision-pi-gen
for python bindings to create a raspberrypi image. I was trying to use it with opencv4.
allwpilib has made changes to accomodate OpenCV4 but I am not sure if they just disabled functions.
cscore has only 3 files with OpenCV issues in allwpilib/cscore/src/main/native/cpp/
When adding and changing the opencv related includes it compiles. The JPEG_QUALITY issue above can be fixed by using the opencv4 equivalent name. One can make current release version of allwpilib compile with opencv4.
I have pkgconfig for opencv4 and its in the pkgconfig path but setup.py does not automatically use it. I don't know how to make that work.
You are correct there are more issues to solve because latest version of allwpilib on github introduces allwpilib/wpiutil/src/main/native/cpp/jni/WPIUtilJNI.cpp which includes jni.h (found in jvm jdk) and "edu_wpi_first_wpiutil_WPIUtilJNI.h" which appears not being a part of the allwpilib. Perhaps it can be somehow exclude from the robotpy-cscore.
I am no expert with creating system packages and perhaps the title of this issue will remain a while longer in effect.
robotpy-cscore is used by
https://github.com/wpilibsuite/FRCVision-pi-gen
for python bindings to create a raspberrypi image.
The frcvision image has all of WPILib, OpenCV, and robotpy-cscore built from source. It does not use any of WPILib's binary artifacts.
I just realised we will want to make sure we can still build on Windows as well, lest we undo all the work I did last season.
Hey, I was trying to install cscore on my mac (with OpenCV 4) and finally, I made it thanks to the previous workarounds on this thread. I am sharing what I have done so anyone who needs it can benefit.
I have done all the changes on this commit add61ae.
Plus I changed the JPEG_QUALITY
and added new imports as told on this thread.
It is successfully compiled and installed.
Changes (additional to add61ae):
cscore_src/cscore/src/main/native/cpp/CvSinkImpl.cpp
13,14d12
< #include <opencv2/core/types_c.h>
< #include <opencv2/videoio/videoio_c.h>
cscore_src/cscore/src/main/native/cpp/CvSourceImpl.cpp
13,14d12
< #include <opencv2/core/types_c.h>
< #include <opencv2/videoio/videoio_c.h>
cscore_src/cscore/src/main/native/cpp/Frame.cpp
400c400
< m_impl->compressionParams.push_back(cv::IMWRITE_JPEG_QUALITY);
---
> m_impl->compressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
431c431
< m_impl->compressionParams.push_back(cv::IMWRITE_JPEG_QUALITY);
---
> m_impl->compressionParams.push_back(CV_IMWRITE_JPEG_QUALITY);
This was done in #81.
(Filing this so people don't waste time trying to get this working with OpenCV 4. tl;dr: it doesn't work and it's hard; stick with OpenCV 3 for now.)
OpenCV 4 appears to install headers to /usr/include/opencv4 instead of /usr/include. It seems like the intended way to discover the correct include path is to call pkg-config:
pkg-config --cflags opencv4
. (One can trick distutils to pass through a-I
by setting $CFLAGS, but obviously that's a terrible suggestion.)However, once you convince distutils to tell gcc to look for the OpenCV headers in the right spot...