Issue with T-API(with OpenCL) python3 - python-3.x

I'm experimenting with T-Api of opencv python. Currently I'm trying to convert a normal RGB image to gray scale and save it with T-Api enabled. Here's the snippet
import cv2
import dlib
im = cv2.UMat(cv2.imread('input.png',1))
print(im)
imMat = cv2.UMat(im)
gray = cv2.cvtColor(imMat,cv2.COLOR_BGR2GRAY)
cv2.imwrite('gray.png',gray)
The output is as follows along with the error
<cv2.UMat object at 0x7fd1e400e378>
<cv2.UMat object at 0x7fc97d0ec390>
Segmentation fault (core dumped)
I have tried this before the above operations
cv2.ocl.setUseOpenCL(True)
print(cv2.ocl.haveOpenCL())
The above print statement is outputting false, I was thinking I need to compile by opencv with OpenCL support inorder for cv2.UMat to work but i'm able to print out both im outputs. I copied the code from this example, it seems to work fine
import cv2
img = cv2.UMat(cv2.imread("image.jpg", cv2.IMREAD_COLOR))
imgUMat = cv2.UMat(img)
gray = cv2.cvtColor(imgUMat, cv2.COLOR_BGR2GRAY)
gray = cv2.GaussianBlur(gray, (7, 7), 1.5)
gray = cv2.Canny(gray, 0, 50)
cv2.imshow("edges", gray)
cv2.waitKey();
Where exactly am I going wrong?

You should rebuild with CMake using the flag WITH_OPENCL=ON and WITH_OPENCLAMDFFT=ON, WITH_OPENCLAMDBLAS=ON if you have AMD’S FFT and BLAS libraries. source

Related

OpenCV with Nvidia VPI (Vision Programming Interface), core dumped

I'm playing around with Vision Programming Interface (VPI) and trying to bend images. I came across this Lens Distortion Correction example (https://docs.nvidia.com/vpi/algo_ldc.html) and added some code so it takes an input image and shows the undistorted output image. The following code runs fine and I'm able to view the output image.
I'd like to run it in a loop for a video input. As soon as I uncomment the "videoCapture" line, I get the following error:
"Segmentation fault (core dumped).
Anyone able to help me use this code for video input?
import vpi
import numpy as np
import cv2
import PIL
from PIL import Image
img = cv2.imread('input.jpeg')
#cap = cv2.VideoCapture(0)
vpi_image = vpi.asimage(np.asarray(img))
grid = vpi.WarpGrid((2064,1544))
sensorWidth = 7.12
focallength = 3.5
f = focallength * (2064 / sensorWidth)
K = [[f, 0, 2064/2],
[0, f, 1544/2]]
X = np.eye(3,4)
warp = vpi.WarpMap.fisheye_correction(grid, K=K, X=X,
mapping=vpi.FisheyeMapping.EQUIDISTANT,
coeffs=[-0.01, 0.22])
with vpi.Backend.CUDA:
output = vpi_image.remap(warp, interp=vpi.Interp.CATMULL_ROM, border=vpi.Border.ZERO)
with output.rlock():
output = Image.fromarray(output.cpu()).save('output.jpeg')
pil_image = PIL.Image.open('output.jpeg').convert('RGB')
cv2_image = np.array(pil_image)
cv2_image = cv2_image[:, :, ::-1].copy()
cv2_image = cv2.resize(cv2_image, (920,590))
img = cv2.resize(img, (920, 590))
sbs = cv2.hconcat([img, cv2_image])
cv2.imshow("sbs", sbs)
cv2.waitKey(0)

Pipe numpy array to virtual video device

I want to pipe images to a virtual video device (e.g. /dev/video0), the images are created inside a loop with the desired frame rate.
In this minimal example i only two arrays which alternate in the cv2 window. Now i look for a good solution to pipe the arrays to the virtual device.
I saw that ffmpeg-python can run asynchronous with ffmpeg.run_async(), but so far i could not make anything work with this package.
example code without the ffmpeg stuff:
#!/usr/bin/env python3
import cv2
import numpy as np
import time
window_name = 'virtual-camera'
cv2.namedWindow(window_name, cv2.WINDOW_GUI_EXPANDED)
img1 = np.random.uniform(0, 255, (1080, 1440, 3)).astype('uint8')
img2 = np.random.uniform(0, 255, (1080, 1440, 3)).astype('uint8')
for i in range(125):
time.sleep(0.04)
if i % 2:
img = img1
else:
img = img2
cv2.imshow(window_name, img)
cv2.waitKey(1)
cv2.destroyAllWindows()
First of all, you would have to setup a virtual camera, with for example v4l2loopback. See here for how to install it (ignore the usage examples).
Then, you can just write to the virtual camera like to a normal file (that is, let openCV write the images to say /dev/video0; how to do that you have to find out yourself because im not an expert with openCV).
In the end, you can use ffmpeg-python with /dev/video0 as input file, do something with the video, and that's it !
As Programmer wrote in his answer, it is possible to create a dummy device with the package v4l2loopback. To publish images, videos or the desktop to the dummy device was already easy with ffmpeg, but i want to pipe it directly from the python script - where i capture the images - to the dummy device. I still think it's possible with ffmpeg-python, but i found this great answer from Alp which sheds light on the darkness. The package pyfakewebcam is a perfect solution for the problem.
For the sake of completeness, here is my extended minimal working example:
#!/usr/bin/env python3
import time
import cv2
import numpy as np
import pyfakewebcam
WIDTH = 1440
HEIGHT = 1080
DEVICE = '/dev/video0'
fake_cam = pyfakewebcam.FakeWebcam(DEVICE, WIDTH, HEIGHT)
window_name = 'virtual-camera'
cv2.namedWindow(window_name, cv2.WINDOW_GUI_EXPANDED)
img1 = np.random.uniform(0, 255, (HEIGHT, WIDTH, 3)).astype('uint8')
img2 = np.random.uniform(0, 255, (HEIGHT, WIDTH, 3)).astype('uint8')
for i in range(125):
time.sleep(0.04)
if i % 2:
img = img1
else:
img = img2
fake_cam.schedule_frame(img)
cv2.imshow(window_name, img)
cv2.waitKey(1)
cv2.destroyAllWindows()

trying to convert a grayscale image to binary, hope anyone can help me

I have a text file from a thermal camera, I read it as an image with opencv python and it works, then I convert it to gray scale image and it works as well! so I can see the person in the image, the problem is that when I convert it to binary I get a blank black image and I need to draw contours around the person's face. So I wonder what might be the problem.
Hint: The text file is filled with temperature values, when I read it it views the whole person and then I do thresholding to the text file to make the values between 32.0 and 37.0 so that I would show only the face area and it works fine until I try to convert it to binary form.
Thanks in advance.
drive.google.com/file/d/1KgHmPAwcL_uPzVxwkigcQgCsY3jFjx8T/… #link to the file
import numpy as np
import cv2 as cv
import matplotlib.pyplot as plt
import os
text=np.loadtxt('1_thermal.txt') #the text file of the image
text[text < 32.0]=0 #threshholding to plot and save only the face
text[text > 37.0]=0
plt.imshow(text,cmap='jet')
plt.savefig('text.png', dpi=300, bbox_inches='tight')
plt.show()
person = cv.imread('text.png')
plt.imshow(cv.cvtColor(person, cv.COLOR_BGR2RGB))
cv.imwrite('person.jpg', person)
# get binary image and apply Gaussian blur
person_gray = cv.cvtColor(person, cv.COLOR_BGR2GRAY)
person_preprocessed = cv.GaussianBlur(person_gray, (5, 5), 0)
cv.imwrite('person-Gray.png', person_preprocessed)
plt.imshow(cv.cvtColor(person_preprocessed, cv.COLOR_GRAY2RGB))
You can load the image into a Numpy array like this:
import numpy as np
# Load image
im = np.loadtxt('thermal.txt')
If we check im.dtype and im.shape, they are:
float64, (288, 382)
Now you want a binary image. I presume you mean it will only have values of True/False, so we will need a threshold. As the face is everything above 32, we will use 32 as the threshold:
# Threshold - greater than 32 becomes True, all else becomes False
binary = im > 32
binary will now be True where the face is and False elsewhere, but I guess you want an image that is black (0) where the background is, and white (255) elsewhere. So you want:
# Convert from False/True, to 0/255 and save
binary = (binary*255).astype(np.uint8)
cv2.imwrite('result.png', binary)
That gives:

using opencv LineSegmentDetector to find line of an image

i have a color image and i should use opencv LineSegmentDetector algorithm to detect lines of the rectangles in the image
Here is my image:
i'm using this code :
import cv2
img = cv2.imread("rectangles.jpg",0)
#Create default parametrization LSD
lsd = cv2.createLineSegmentDetector(0)
#Detect lines in the image
lines = lsd.detect(img)[0]
#Draw detected lines in the image
drawn_img = lsd.drawSegments(img,lines)
#Show image
cv2.imshow("LSD",drawn_img )
cv2.waitKey(0)
and i'm getting this errpr:
<ipython-input-18-93ae667b0648> in <module>()
3
4 #Create default parametrization LSD
----> 5 lsd = cv2.createLineSegmentDetector(0)
6
7 #Detect lines in the image
error: OpenCV(4.1.0) C:\projects\opencv-python\opencv\modules\imgproc\src\lsd.cpp:143: error: (-213:The function/feature is not implemented) Implementation has been removed due original code license issues in function 'cv::LineSegmentDetectorImpl::LineSegmentDetectorImpl'
i checked open-cv version 4.1 documentation to use this method and here is the page , but i dont understand how should i use this method.
any help is appreciated.
Did you read the error message?
error: OpenCV(4.1.0) C:\projects\opencv-python\opencv\modules\imgproc\src\lsd.cpp:143: error: (-213:The function/feature is not implemented)
Implementation has been removed due original code license issues in function 'cv::LineSegmentDetectorImpl::LineSegmentDetectorImpl'
The class is not available due to license issues.
You can see that here in the original source.
You can also use Fast Line Detector which is available in OpenCV 4.1.
import cv2
img = cv2.imread("rectangles.jpg",0)
#Create default Fast Line Detector (FSD)
fld = cv2.ximgproc.createFastLineDetector()
#Detect lines in the image
lines = fld.detect(img)
#Draw detected lines in the image
drawn_img = fld.drawSegments(img,lines)
#Show image
cv2.imshow("FLD", drawn_img)
cv2.waitKey(0)
Result:

Python - CV2 strange behavior on Spyder while processing images

I am working on YOLO network for object detection. I am getting unexpected result while working on images. My findings are:
While drawing rectangle on an image using cv2.rectangle() method, it changes the image type as NoneType on Spyder IDE, while it remains same (i-e: numpy.ndarray) on Jupyter-notebook.
The code as follows:
img = cv2.imread('1527502132336.jpeg', 1)
result = tfnet.return_predict(img)
tl = (result[0]['topleft']['x'], result[0]['topleft']['y'])
br = (result[0]['bottomright']['x'], result[0]['bottomright']['y'])
label = result[0]['label']
img = cv2.rectangle(img, tl, br, (255, 0, 0), 3)
type(img)
I want to get the same result as returned by Jupyter for further processing. Why I am getting this strange behavior.

Resources