Using OpenCV's Image Hashing Module from Python - python

I want to use OpenCV's perceptual hashing functions from Python.
This isn't working.
import cv2
a_1 = cv2.imread('a.jpg')
cv2.img_hash_BlockMeanHash.compute(a_1)
I get:
TypeError: descriptor 'compute' requires a 'cv2.img_hash_ImgHashBase' object but received a 'numpy.ndarray'
And this is failing too
a_1_base = cv2.img_hash_ImgHashBase(a_1)
cv2.img_hash_BlockMeanHash.compute(a_1_base)
I get:
TypeError: Incorrect type of self (must be 'img_hash_ImgHashBase' or its derivative)
Colab notebook showing this:
https://colab.research.google.com/drive/1x5ZxMBD3wFts2WKS4ip3rp4afDx0lGhi

It's a common compatibility gap that the OpenCV python interface has with the C++ interface (i.e. the classes don't inherit from each other the same way). There are the *_create() static functions for that.
So you should use:
hsh = cv2.img_hash.BlockMeanHash_create()
hsh.compute(a_1)
In a copy of your collab notebook:
https://colab.research.google.com/drive/1CLJNPPbeO3CiQ2d8JgPxEINpr2oNMWPh#scrollTo=OdTtUegmPnf2

pip install opencv-python
pip install opencv-contrib-python #img_hash in this one
(https://pypi.org/project/opencv-python/)

Here I show you how to compute 64-bit pHash with OpenCV.
I defined a function which returns unsigned, 64-bit integer pHash from a color BGR cv2 image passed-in:
import cv2
def pHash(cv_image):
imgg = cv2.cvtColor(cv_image, cv2.COLOR_BGR2GRAY);
h=cv2.img_hash.pHash(imgg) # 8-byte hash
pH=int.from_bytes(h.tobytes(), byteorder='big', signed=False)
return pH
You need to have installed and import cv2 for this to work.

Related

module 'skimage.data' has no attribute 'imread'

import skimage
image = skimage.data.imread("my_image.png")
I used this code to read an image, but I got an error as "skimage.data" has no attribute "imread".
My skimage version is 0.18.1. What has to be changed in this to read an image?
The error is straightforward. You try to call the imread function in the data module, but there is no such function in this module. Call
skimage.io.imread('blah.png')
instead.

(-212:Parsing error) Unsupported activation: mish in function 'ReadDarknetFromCfgStream'

I am new to object detetctio and trying to run code for simple object detection on google colab, please help me with the solution
import cv2
import numpy as np
import matplotlib.pyplot as plt
import cvlib as cv
from cvlib.object_detection import draw_bbox
from numpy.lib.polynomial import poly
img = cv2.imread("/content/banner.jpg")
img1 = cv2.cvtColor(img,cv2.COLOR_BGR2RGB)
plt.figure(figsize=(10,10))
plt.axis("off")
plt.imshow(img1)
plt.show()
box, label,count = cv.detect_common_objects(img)
#output = draw_bbox(img, box,label, count)
but it is giving error as
error: OpenCV(3.4.3) /io/opencv/modules/dnn/src/darknet/darknet_io.cpp:552: error: (-212:Parsing error) Unsupported activation: mish in function 'ReadDarknetFromCfgStream'
Are you running object detection on Yolov4?
If yes, please note that Yolov4 is not supported by Opencv 4.2.0 and 4.3.0.
Try to download the last version in master branch support YoloV4 (according to KyloEntro)
Personally, I have upgraded opencv-python to version 4.5.3.56, and there is no more error!
please update your opencv, more recent versions have a proper mish activation
import cvlib as cv
DONT use 3rd party libs built on top of opencv, since you have no control about versioning, and noone knows about those enough to help 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.

Jedi completion does not work for Image object created using Image.open() method

I am using deoplete-jedi to provide auto-completions inside Neovim. I found out that auto-completion does not work if I create an Image object instance using Image.open() method when using Pillow. But for Image instance created using Image.new() method, the auto-completion works correctly.
After a lot of debuging, I finally find out the reason. Because the Jedi package can not provide completions for Image instance created by Image.open() method.
The below code shows the differences:
import jedi
source1 = '''
from PIL import Image
im = Image.new('test.jpg', (128, 128))
im.
'''
script1 = jedi.Script(source1, 4, len('im.'), 'example1.py')
print(script1.completions())
source2 = '''
from PIL import Image
im = Image.open('test.jpg')
im.
'''
script2 = jedi.Script(source2, 4, len('im.'), 'example2.py')
print(script2.completions())
Since the two methods both return an Image object, I do not know why the auto-completion behaves differently.
Version info
Python: Python 3.6.8
jedi: 0.13.3
Pillow: 5.2.0
The problem typically is that things like Image.open() do things like caching, where it's pretty much impossible to infer the right type.
In this example (look at https://github.com/python-pillow/Pillow/blob/master/src/PIL/Image.py#L2690), Jedi tries to follow im -> _open_core(...) -> other im -> factory(...) -> factory seems like factory, accept = OPEN[i] -> but what is OPEN -> it's defined as an empty {}, and filled in register_open() or from the outside -> register_open is not called in the same file.
And that's where Jedi stops searching for solutions. So you can see it's not always possible to infer types. Even I'm not sure what the returned type will be and I tried to look at it for 10 minutes. The solution is usually stubs/type annotations for this.

How can I get the volume of sound of a video in Python using moviepy?

I want to get the volume of sound of a video so I use the following:
import numpy as np # for numerical operations
from moviepy.editor import VideoFileClip, concatenate
clip = VideoFileClip("soccer_game.mp4")
cut = lambda i: clip.audio.subclip(i,i+1).to_soundarray(fps=22000)
volume = lambda array: np.sqrt(((1.0*array)**2).mean())
volumes = [volume(cut(i)) for i in range(0,int(clip.audio.duration-2))]
But I get these errors:
Exception AttributeError: "VideoFileClip instance has no attribute 'reader'" in <bound method VideoFileClip.__del__ of <moviepy.video.io.VideoFileClip.VideoFileClip instance at 0x084C3198>> ignored
WindowsError: [Error 5] Access is denied
I am using IPython notebook and Python 2.7.
I assume something doesn't have the appropriate permissions. I have changed run this program as an administrator for ffmpeg.exe, ffplay.exe, ffprobe.exe.
I fixed a bug today that may have caused your problem, would you mind upgrading and trying again ? If it still doesn't work, I'll need to know your windows version.
Rather than doing own calculations, I would recommend to use an existing library or tool that considers the human-perceived loudness.
For example, ffmpeg can measure the loudness based on the EBU R 128 recommendation (in LUFS).
This discussion recommends pyloudnorm.

Categories