Using value pointer is unsafe and deprecated error in Opencv Python - python

I am new to opencv and python and was learning the basics from the docs. I was learning about the trackbar in opencv (python).
I wrote the same code as shown in the docs here. (Note the version is 4.5.3)
Here's my code:
import numpy as np
import cv2 as cv
def nothing(x):
pass
# Create a black image, a window
img = np.zeros((300,512,3), np.uint8)
cv.namedWindow('image')
# create trackbars for color change
cv.createTrackbar('R','image',0,255,nothing)
cv.createTrackbar('G','image',0,255,nothing)
cv.createTrackbar('B','image',0,255,nothing)
# create switch for ON/OFF functionality
switch = '0 : OFF \n1 : ON'
cv.createTrackbar(switch, 'image',0,1,nothing)
while(1):
cv.imshow('image',img)
k = cv.waitKey(1) & 0xFF
if k == 27:
break
# get current positions of four trackbars
r = cv.getTrackbarPos('R','image')
g = cv.getTrackbarPos('G','image')
b = cv.getTrackbarPos('B','image')
s = cv.getTrackbarPos(switch,'image')
if s == 0:
img[:] = 0
else:
img[:] = [b,g,r]
cv.destroyAllWindows()
When I run this code, I get the following annoying long warning:
Using 'value' pointer is unsafe and deprecated. Use NULL as value pointer. To fetch trackbar value setup callback.
This is the full warning message if anyone wants to refer:
[ WARN:0] global C:\Users\runneradmin\AppData\Local\Temp\pip-req-build-q3d_8t8e\opencv\modules\highgui\src\window.cpp (704) cv::createTrackbar UI/Trackbar(R#image): Using 'value' pointer is unsafe and deprecated. Use NULL as value pointer. To fetch trackbar value setup callback.
I tried to understand what it is trying to say, but couldn't understand much. AFAIU, the error is in the line (and subsequent):
r = cv.getTrackbarPos('R','image')
Even thought it is a warning, I would like to get rid of it, as it uses the word unsafe and deprecated.
I have opencv-python of version 4.5.3.56. I've tried getting through the docs, but seems they are the same as for older versions, and this particular feature is deprecated in my version.
Can anyone suggest me what should be done to avoid this?

this bug in 4.5.3 is already reported and fixed (at least for python)
however, unless you rebuild it locally, you will have to wait for the next pypi release ;(

Related

Sending numpy array (image) to c++ library with ctypes

I'm trying to make a python program that can run Photoshop Plugins by using this DLL library from Spetric - https://github.com/spetric/Photoshop-Plugin-Host
I need to send an image loaded by opencv to the dll (while I can read c++ I cannot program in it and have never been able to get the dll to compile for edits such as loading the image directly from a filename)
The description of the function is
pspiSetImage(TImgType type, int width, int height, void *imageBuff, int imageStride, void *alphaBuff = 0, int alphaStride = 0);
I have tried several suggestions and solutions found here on stackoverflow but they all result in the same thing "OSError: exception: access violation writing 0x00000000"
Which is weird because I thought the idea was to pass in a pointer to a long buffer of data and that number wouldn't be 0. I've checked the value/output and it never is zero that I pass in.
I have tried accessing the __array_interface++['data'][0], using ctypes.data_as built into the numpy object, various versions of POINTER and c_void_p. My fundamental misunderstanding of what's needed and how to get it and pass it is my problem.
Are there any suggestions or helpful hints to point me in the right direction?
EDIT: Here is the code I'm currently working with
import ctypes
import cv2
plugins = {}
def main(args=None):
plugin_host = ctypes.CDLL('.\\pspiHost.dll')
plugin_host.pspiSetPath(".\\8bf filters\\")
# Any image will do, I used a PNG to test alpha transparency
im = cv2.imread('.\\fish.png', cv2.IMREAD_UNCHANGED)
array = im.ctypes.data_as(ctypes.POINTER(ctypes.c_void_p))
width = im.shape[0]
height = im.shape[1]
# 1 in first parameter is for RGBA format, I'm using a png with transparency
plugin_host.pspiSetImage(ctypes.c_int(1),
ctypes.c_int(width),
ctypes.c_int(height),
array,
ctypes.c_int(0))
if __name__=='__main__':
main()
This is a duplicate of [SO]: C function called from Python via ctypes returns incorrect value (#CristiFati's answer), but I'm going to detail.
When working with CTypes, the .dll must export functions using C compatible interface (extern "C"), while pspiSetImage seems to be C++ (default arguments).
Also check [SO]: How to write a function in C which takes as input two matrices as numpy array (#CristiFati's answer) for details converting NumPy arrays.
Here's a snippet that should fix things.
import ctypes as cts
import cv2
import numpy as np
plugin_host = ctypes.CDLL(r".\pspiHost.dll")
pspiSetPath = plugin_host.pspiSetPath
pspiSetPath.argtypes = (cts.c_wchar_p,) # Got this from the passed argument
pspiSetPath.restype = None # void return?
# ...
img = cv2.imread(r".\fish.png", cv2.IMREAD_UNCHANGED)
# ...
pspiSetImage = plugin_host.pspiSetImage
pspiSetImage.argtypes = (
cts.c_int, cts.c_int, cts.c_int,
np.ctypeslib.ndpointer(dtype=img.dtype, shape=img.shape, flags="C"), #cts.c_void_p, # Extra checks for NumPy array
cts.c_int,
cts.c_void_p, # Not sure what the array properties are
cts.c_int,
)
pspiSetImage.restype = None # void return?
# ...
pspiSetPath(".\\8bf filters\\")
img_stride = img.strides[0]
pspiSetImage(
1, *img.shape[:2],
img, #np.ctypeslib.as_ctypes(img),
img_stride, None, 0
)
Notes:
Not sure what the function does internally, but bear in mind that the array has 3 dimensions (and you're only passing 2), also its dtype
Also, after taking a (shallow) look at Photoshop-Plugin-Host sources, imageStride argument should (most likely) be img.strides[0]
Function argument imageBuff is tailored on this specific array. If you need to call it multiple times, with different arrays (shapes and dtypes), you should take the generic approach (have a cts.c_void_p argument and convert it via np.ctypeslib.as_ctypes (or img.ctypes.data_as))

Python Mediapipe module call

mediapipe==0.8.10.1
I'm trying to make a project based on mediapipe, and I've installed the package normally using
pip install mediapipe
I'm running this in the VS Code editor within a venv which has access to global packages,
import cv2
import mediapipe as mp
# why do I need to do this, instead of simply
# "mpHands = mp.solutions.hands"
# to access the hands function because otherwise it doesn't recognize the module
mpHands = mp.solutions.mediapipe.python.solutions.hands
Hands = mpHands.Hands() # doesn't recognize unless I do the entire line above
capture = cv2.VideoCapture(0)
while True:
ret, img = capture.read()
cv2.imshow("res", img)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
From the google github and other tutorials, "mp.solutions.hands" would be the usual way to call the module, but after some head scratching I've noticed that I need to use "mp.solutions.mediapipe.python.solutions.hands"
to access the "Hands()" module, otherwise it's unrecognized.
Moreover this only happens with mediapipe and not with, for example opencv.
I'm really not sure why this happens; I am new to package handling so any advice would be appreciated,
thank you.

cv2.cuda_CascadeClassifier in python

I am attempting to use the Haarclassifier from opencv cuda, for this I found the object cv.cuda_CascadeClassifier. However, assigning cv.cuda_CascadeClassifier() to a variable spit the following error:
this object has no ''load'' attribute. I could successfully verify it
by printing their dir() print(dir(cv.cuda_CascadeClassifier)).
Is there any other way to call this object or did anyone effectively exploite the cascadeclassifier with opencv cuda?
thx
The lack of documentation for the python API really is a pain. Speaking about the version 4.5 of OpenCV, you have to call the create method when reading a xml cascade file or it'll yield segmentation fault when trying to detect. In my experience you'll also need to convert to gray scale or it will yield (-215:Assertion failed) src.type() == CV_8UC1.
Here's my working code on OpenCV 4.5.1:
import cv2
img = cv2.imread('./img_sample.jpg')
cascade = cv2.cuda_CascadeClassifier.create('./cascade_file.xml')
gray_img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
cuFrame = cv2.cuda_GpuMat(gray_img)
result = cascade.detectMultiScale(cuFrame).download() # download() gets the result as UMat
if result is not None:
print(result[0])
I hope this answers your question about the cuda version usage.
This is most likely due to the use of a version of openCV between 4.0.0 and 4.3.0, In those versions cuda_CascadeClassifier was disabled. In 4.4.0 This functionallity was brought back. (https://github.com/opencv/opencv_contrib/pull/2554/files)
Even though this seems to work fine in C++ it gives me a segmentation fault using the python wrapper using the following code:
classifier_cuda = cv2.cuda_CascadeClassifier('cascades_file.xml')
while True:
success, frame = vidcap.read()
cuFrame = cv2.cuda_GpuMat(frame)
result = classifier_cuda.detectMultiScale(cuFrame)
print (result)
Any solutions?
As already Breno Alef wrote, the problem of OpenCV for Python is the lack of documentation and also of some code examples, which makes difficult to understand how to write correctly Python code to use OpenCV.
Looking at the documentation of the cuda_CascadeClassifier or using the Python built-in function help() you can see that the cuda_CascadeClassifier is a subclass of cv.Algorithm, which contains the load() method, but the problem is the way cuda_CascadeClassifier works is a bit different from the Cascade class declared in opencv2/objdetect.hpp.

Python OpenCV chamerMatching function reference

I have searched everywhere and I find it truly amazing that there is no reference on the chamerMatching function, especially in Python. Someone else also had the same problem with no answer:
I don't really want to know about the algorithm - I know how the algorithm works - I want to know how to call it in Python and retrieve the costs, results and bestfit. I have tried the following code.
import numpy as np
import cv2
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
frame = cv2.GaussianBlur(frame, (13, 13), 0)
frame = cv2.cvtColor(frame,cv2.COLOR_BGR2GRAY)
frame = cv2.adaptiveThreshold(frame,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2)
templ = cv2.imread("template.png",cv2.CV_LOAD_IMAGE_GRAYSCALE)
cannyframe = cv2.Canny(frame,5,50,apertureSize=3)
cannytempl = cv2.Canny(templ,5,50,apertureSize=3)
cv2.imshow("cannyframe",cannyframe)
cv2.imshow("cannytempl", cannytempl)
cv2.waitKey(0)
#The line below, and NOT any other line, crashes the program
cv2.chamerMatching(cannytempl,cannyframe)
All of it runs fine except the final call to the chamerMatching function which causes the python interpreter to crash and stop working for some reason with a message that looks like this:
With absolutely zero documentation on the function, I can't figure out why.
EDIT:
The code above now includes all the required lines to run and below is template.png.
i don't know if you still need this information. But I also needed chamfer matching for my research. And here's what I found after encountering the same dilemma as you've had.
http://code.opencv.org/issues/3602
:)

Python CV Webcam - Null Argument To Internal Routine

having recently learned the basics of python, I thought I would dive in with a small project to build on.
A webcam application. I would then add tools as I developed my skills.
I have installed matplotlib, CV, numpy, and various others,the code I found:
import cv
cv.namedWindow("lll")
cap = cv.VideoCapture(0)
while( cap.isOpened() ) :
ret,img = cap.read()
cv.imshow("lll",img)
k = cv.waitKey(10)
if k == 27:
break
Now the initial "video Source" dialogue comes up, I select my webcam and press OK.
Then I get an error:
while(cap.isOpened()):
SystemError: null argument to internal routine
Done a bit of googling. Found others with the same issue but no resolution...
Any tips?
Sorry for not addressing your specific problem, but you can always use the newer cv2 module:
import cv2
cv2.namedWindow("lll")
cap = cv2.VideoCapture(0)
while True:
ret,img = cap.read()
cv2.imshow("lll",img)
k = cv2.waitKey(10)
if k == 27:
break
Sounds like something that would require digging into the source of PyCV (or whatever the interface to OpenCV is called) to fix. My tip to you would be to go to the OpenCV IRC-channel and ask or/and file a bug report.

Categories