I try to load some images into an RDD and use the face recognition library(https://github.com/ageitgey/face_recognition) to compare different images. Following code work
import face_recognition
import numpy as np
from io import BytesIO
from PIL import Image
from pyspark import SparkContext
sc = SparkContext(appName="LoadingImage")
images = sc.binaryFiles("./images/")
image_to_array = lambda rawdata: np.asarray(Image.open(BytesIO(rawdata)))
i_arr = images.values().map(image_to_array)
new_encoding = face_recognition.face_encodings(i_arr.first())
next_encoding = face_recognition.face_encodings(i_arr.first())
result = face_recognition.compare_faces([new_encoding[0]], next_encoding[0])
print(result)
However, when I try to map face_encodings function to all the elements inside the RDD, it always gives me an error:
RuntimeError: Expected writable numpy.ndarray with shape set.
img_to_encodings = lambda img: face_recognition.face_encodings(img)[0]
i_arrm = i_arr.map(img_to_encodings)
result = face_recognition.compare_faces([i_arrm.first()], i_arrm.first())
print(result)
The error is from dlib library, but I reckon I did something wrong with spark. Any idea how to solve this?
The frame returned by picamera has flag set to false i.e Writable : False.
Set frame flag to true so that face_recognition package can use it. Code Snippet:
image.setflags(write=True)
For Demo Code Have A Look:
#import the necessary packages
from picamera.array import PiRGBArray
from picamera import PiCamera
import time
import cv2
#initialize the camera and grab a reference to the raw camera capture
camera = PiCamera()
camera.resolution = (640, 480)
camera.framerate = 32
rawCapture = PiRGBArray(camera, size=(640, 480))
#allow the camera to warmup
time.sleep(0.1)
#capture frames from the camera
for frame in camera.capture_continuous(rawCapture, format="bgr", use_video_port=True):
# grab the raw NumPy array representing the image, then initialize the timestamp
# and occupied/unoccupied text
image = frame.array
image.setflags(write=True)
cv2.imshow("Frame", image)
key = cv2.waitKey(1) & 0xFF
# clear the stream in preparation for the next frame
rawCapture.truncate(0)
# if the q key was pressed, break from the loop
if key == ord("q"):
break
cv2.destroyAllWindows()
Related
I tried get image from my gige camera. In the camera's own software its working just fine, but when I do it with harvesters my image has a weird grid and I don't know why is it there and how to remove it. I need this for a stereovision project. Any idea?
Don't mind the brightness I tried it with higher expo as well, it did not changed a thing. :D
enter image description here
import genicam.genapi as ge
import cv2
from harvesters.core import Harvester
import matplotlib.pyplot as plt
import numpy as np
# Create a Harvester object:
h = Harvester()
# Load a GenTL Producer; you can load many more if you want to:
h.add_file("C:/Program Files\MATRIX VISION/mvIMPACT Acquire/bin/x64/mvGenTLProducer.cti")
# Enumerate the available devices that GenTL Producers can handle:
h.update()
# Select a target device and create an ImageAcquire object that
# controls the device:
ia = h.create(0)
ia2 = h.create(1)
# Configure the target device; it looks very small but this is just
# for demonstration:
ia.remote_device.node_map.Width.value = 1456
ia.remote_device.node_map.Height.value = 1088
# ia.remote_device.node_map.PixelFormat.symbolics
ia.remote_device.node_map.PixelFormat.value = 'BayerRG8'
ia2.remote_device.node_map.Width.value = 1456
ia2.remote_device.node_map.Height.value = 1088
# ia2.remote_device.node_map.PixelFormat.symbolics
ia2.remote_device.node_map.PixelFormat.value = 'BayerRG8'
ia.remote_device.node_map.ChunkSelector.value = 'ExposureTime'
ia.remote_device.node_map.ExposureTime.set_value(100000.0)
ia2.remote_device.node_map.ChunkSelector.value = 'ExposureTime'
ia2.remote_device.node_map.ExposureTime.set_value(100000.0)
# Allow the ImageAcquire object to start image acquisition:
ia.start()
ia2.start()
# We are going to fetch a buffer filled up with an image:
# Note that you'll have to queue the buffer back to the
# ImageAcquire object once you consumed the buffer; the
# with statement takes care of it on behalf of you:
while True:
with ia.fetch() as buffer:
component = buffer.payload.components[0]
_2d = component.data.reshape(1088, 1456)
img = _2d
img = cv2.resize(img,(640,480))
cv2.imshow('right',img)
cv2.imwrite('test_left.png',img)
cv2.waitKey(10)
with ia2.fetch() as buffer:
component = buffer.payload.components[0]
_2d = component.data.reshape(component.height, component.width)
img2 = _2d
img2 = cv2.resize(img2, (640, 480))
cv2.imshow('left', img2)
cv2.imwrite('test_right.png',img2)
cv2.waitKey(10)
ia.stop()
ia2.stop()
ia.destroy()
ia2.destroy()
h.reset()
I just had to convert it to Gray or RGB with cvtColor, and its working.
Thanks anyway.
I'm trying to use an example from
https://github.com/ageitgey/face_recognition
for face detection on Raspberry Pi.
This is the 'facerec_on_raspberry_pi.py' code:
# This is a demo of running face recognition on a Raspberry Pi.
# This program will print out the names of anyone it recognizes to the console.
# To run this, you need a Raspberry Pi 2 (or greater) with face_recognition and
# the picamera[array] module installed.
# You can follow this installation instructions to get your RPi set up:
# https://gist.github.com/ageitgey/1ac8dbe8572f3f533df6269dab35df65
import face_recognition
import picamera
import numpy as np
# Get a reference to the Raspberry Pi camera.
# If this fails, make sure you have a camera connected to the RPi and that you
# enabled your camera in raspi-config and rebooted first.
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)
# Load a sample picture and learn how to recognize it.
print("Loading known face image(s)")
obama_image = face_recognition.load_image_file("obama_small.jpg")
obama_face_encoding = face_recognition.face_encodings(obama_image)[0]
# Initialize some variables
face_locations = []
face_encodings = []
while True:
print("Capturing image.")
# Grab a single frame of video from the RPi camera as a numpy array
camera.capture(output, format="rgb")
# Find all the faces and face encodings in the current frame of video
face_locations = face_recognition.face_locations(output)
print("Found {} faces in image.".format(len(face_locations)))
face_encodings = face_recognition.face_encodings(output, face_locations)
# Loop over each face found in the frame to see if it's someone we know.
for face_encoding in face_encodings:
# See if the face is a match for the known face(s)
match = face_recognition.compare_faces([obama_face_encoding], face_encoding)
name = "<Unknown Person>"
if match[0]:
name = "Barack Obama"
print("I see someone named {}!".format(name))
Code is working fine with CSI camera, but how can I change to work with USB webcam?
Thanks
You can use opencv API directly.
Instead of creating a PiCamera object like:
camera = picamera.PiCamera()
camera.resolution = (320, 240)
output = np.empty((240, 320, 3), dtype=np.uint8)
Try:
import cv2
camera = cv2.VideoCapture(0) # 0 is the first camera
Then, when reading an image, replace:
camera.capture(output, format="rgb")
With:
_, output = camera.read() # To read the image in the camera native resolution
output = cv2.resize(output, (320, 240)) #To get the image in the same size as expected
When I run the code, I got this error:
[ERROR:0] global /io/opencv/modules/videoio/src/cap.cpp (116) open VIDEOIO(CV_IMAGES): raised OpenCV exception:
OpenCV(4.1.2) /io/opencv/modules/videoio/src/cap_images.cpp:267: error: (-215:Assertion failed) number < max_number in function 'icvExtractPattern'
Please show me how to fix it. Thank you very much.
And this is my source code:
# Program for finding the location of a person based a difference images
# The video file name should be specified.
import os
from typing import Dict, List, Tuple
import datetime
from datetime import datetime
import numpy as np
import matplotlib.pyplot as plt
#import sklearn
#from sklearn import metrics
#from sklearn import neural_network
#import sklearn_util
import cv2
def guess_location(src):
index = np.array([i for i in enumerate(src)])
index_sum_sort10 = index[index[:, -1].argsort()][::-1][0:40].T
location = int(np.average(index_sum_sort10[0]))
return location
def calculate_location(src):
row_max_location = guess_location(np.sum(src, axis=0))
col_max_location = guess_location(np.sum(src, axis=1))
return (row_max_location, col_max_location)
#
# Read video frames from a usb-camera / video file,
# and find the location of the person
#
cap = cv2.VideoCapture(0)
v_filename= '/dev/compact-module/Videodata/2021/03/22/1720_00_006686/entity_video_1616401200006.mp4'
#'/media/qf-zhao/68A01144A0111A60/GrayDiffVideo/Image2019_11_18_08_40_00.avi'
cap = cv2.VideoCapture(v_filename)
th_change = 150
th_value = 30
location_back=(0,0)
while(cap.isOpened()):
ret, frame = cap.read()
diff=cv2.cvtColor(frame, cv2.COLOR_RGB2GRAY)
diff[diff<th_value]=0
if np.max(frame) < th_change:
location=location_back
else:
location = calculate_location(diff)
print("location:", location)
cv2.circle(frame, location, 10, (0,0,255), -1)
cv2.imshow('Result image', frame)
location_back=location
if cv2.waitKey(1) & 0xFF == ord('q'):
break
cv2.destroyAllWindows()
How to scan barcode using Raspberry pi camera module V2
This is the link to my previously asked question about barcode scanning.
To be more specific:
Hardware :
Raspberry pi
and
Raspberry pi camera module v2 :
https://www.amazon.in/Raspberry-Camera-Board-Module-
V2/dp/B071P2S8LG/ref=sr_1_5?s=computers&ie=UTF8&qid=1525942832&sr=1-5&keywords=raspberry+pi+camera+module
I have tried to scan bar code using
1) pyzbar library
2) SimpleCV
3) OpenCV and zbar
Using Pyzbar :
from PIL import Image
import pyzbar.pyzbar as pyzbar
file_path = 'image.png'
with open(file_path, 'rb') as image_file:
image = Image.open(image_file)
image.load()
codes = pyzbar.decode(Image.open('image.png'))
print('QR codes: %s' % codes)
Using SimpleCV :
from SimpleCV import Color,Camera,Display
cam = Camera() #starts the camera
display = Display()
while(display.isNotDone()):
img = cam.getImage() #gets image from the camera
barcode = img.findBarcode() #finds barcode data from image
if(barcode is not None): #if there is some data processed
barcode = barcode[0]
result = str(barcode.data)
print result #prints result of barcode in python shell
barcode = [] #reset barcode data to empty set
img.save(display) #shows the image on the screen
Using OpenCV :
https://www.pyimagesearch.com/2014/11/24/detecting-barcodes-images-python-opencv/
I have tried all three ways to scan barcode but none of them is working.
Using the last code, I am able to detect the barcode location in the image but cannot scan barcode.
Thanks in advance
go through this. it should work.
from pyzbar.pyzbar import decode
from ftplib import FTP
import os
import numpy as np
import cv2
import time
from picamera.array import PiRGBArray
from picamera import PiCamera
fourcc = cv2.VideoWriter_fourcc(*'X264')
def dec(frame):
x=decode(frame)
for i in x:
(x, y, w, h) = i.rect
cv2.rectangle(frame,(x, y),(x + w, y + h),(0, 0, 255),2)
barcodeData = i.data.decode("utf-8")
barcodeType = i.type
return(barcodeData,barcodeType,1)
return('','',0)
camera=PiCamera()
camera.resolution=(1296,730)
camera.framerate=20
rawCapture=PiRGBArray(camera)
time.sleep(0.1)
cv2.namedWindow("Image",cv2.WINDOW_NORMAL)
for frame in camera.capture_continuous(rawCapture,format="bgr",use_video_port=True):
image=frame.array
x,y,p=dec(image)
cv2.imshow("Image",image)
print(x)
print(y)
if cv2.waitKey(2) & 0xFF == ord('q'):
break
rawCapture.truncate(0)
#cap.release()
cv2.destroyAllWindows()
When running the examples from the OpenCV video processing python tutorials, they all pop up in a dedicated window. I know that the IPython notebook can display videos from disk and YouTube, so I wonder if there is a way to direct the OpenCV video playback to the Notebook browser and have it play in the output cell instead of a separate window (preferably without saving it to disk and then playing it from there).
Below is the code from the OpenCV tutorial.
import cv2
cap = cv2.VideoCapture('/path/to/video')
while(True):
# Capture frame-by-frame
ret, frame = cap.read()
# Our operations on the frame come here
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
# Display the resulting frame
cv2.imshow('frame',gray)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# When everything done, release the capture
cap.release()
cv2.destroyAllWindows()
To make the display faster use only IPython.display.display inside the notebook and JPG format instead of PNG. (Note displaying with cv2.imshow natively outside the notebook is much faster, but this is not what the question asks for):
The code below will test all the supported file formats to find the fastest one (extracted from __doc__ with a regex, not reliable)
from IPython.display import clear_output, Image, display, HTML
import cv2
# Read one frame from the camera for testing
video = cv2.VideoCapture(0)
_, frame = video.read()
video.release()
import re
from timeit import timeit
import math
extensions=re.findall(r"\\\*(\.\w*)", cv2.imread.__doc__)
def test(extension):
try:
totalTime=0
numTry=3
for _ in range(numTry):
totalTime+=timeit(lambda: display(Image(data=cv2.imencode(extension, frame)[1])), number=1)
clear_output(wait=True)
return totalTime/numTry, extension
except cv2.error as e: #usually "unsupported file type"
return (math.inf, extension, e)
for x in sorted(
[test(extension) for extension in extensions], key=lambda x: x[0]
): print(x)
In my case, .jpeg is the fastest. Make sure that the browser display also support that extension:
Image(data=cv2.imencode(".jpeg", frame)[1].tobytes())
Then, to play the video:
import cv2
from IPython.display import display, Image
video = cv2.VideoCapture(0)
display_handle=display(None, display_id=True)
try:
while True:
_, frame = video.read()
frame = cv2.flip(frame, 1) # if your camera reverses your image
_, frame = cv2.imencode('.jpeg', frame)
display_handle.update(Image(data=frame.tobytes()))
except KeyboardInterrupt:
pass
finally:
video.release()
display_handle.update(None)
update is a little faster than clear_output + display every time; however compare to the rendering it isn't a significant improvement.
You can do it with Bokeh and probably it is a bit faster.
from bokeh.plotting import figure
from bokeh.io import output_notebook, show, push_notebook
import cv2
import time
output_notebook()
cap = cv2.VideoCapture(0)
ret, frame = cap.read()
frame=cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA) # because Bokeh expects a RGBA image
frame=cv2.flip(frame, -1) # because Bokeh flips vertically
width=frame.shape[1]
height=frame.shape[0]
p = figure(x_range=(0,width), y_range=(0,height), output_backend="webgl", width=width, height=height)
myImage = p.image_rgba(image=[frame], x=0, y=0, dw=width, dh=height)
show(p, notebook_handle=True)
while True:
ret, frame = cap.read()
frame=cv2.cvtColor(frame, cv2.COLOR_BGR2RGBA)
frame=cv2.flip(frame, -1)
myImage.data_source.data['image']=[frame]
push_notebook()
time.sleep(0.3)
The video encoded data (if in a format the browser can decode, eg. h264-encoded in ISO mp4 container) can be displayed using an HTML <video> tag and IPython.core.display.HTML(), this will provide standard playback performance.
The <video> can be a link, or have embedded base64'ed data (the latter is what matplotlib.animation does, for example), and its data can of course be generated in your notebook, using OpenCV (eg. VideoWriter).
Yes. But it will be slooowwww....
Code with Python 3 and OpenCV 3.3 that reads from webcam (from file, just change cv2.VideoCapture("filename.mp4")):
from IPython.display import clear_output, Image, display, HTML
import numpy as np
import cv2
import base64
def arrayShow (imageArray):
ret, png = cv2.imencode('.png', imageArray)
encoded = base64.b64encode(png)
return Image(data=encoded.decode('ascii'))
video = cv2.VideoCapture(0)
while(True):
try:
clear_output(wait=True)
_, frame = video.read()
lines, columns, _ = frame.shape
frame = cv2.resize(frame, (int(columns/4), int(lines/4)))
img = arrayShow(frame)
display(img)
except KeyboardInterrupt:
video.release()
You may need to change IOPub data rate limit.
You can change this in your .jupyter config or just run
jupyter notebook --NotebookApp.iopub_data_rate_limit=1000000000
The keyboard interrupt doesn't work properly, though.
from IPython.display import clear_output, Image, display
import ipywidgets
import cv2
video = cv2.VideoCapture(0)
display_handle=display(None, display_id=True)
image_widget = ipywidgets.Image(format='jpeg')
while True:
try:
clear_output(wait=True)
_, frame = video.read()
lines, columns, _ = frame.shape
frame = cv2.resize(frame, (int(columns/4), int(lines/4)))
image_widget.value =cv2.imencode('.jpeg', frame)[1].tobytes()
display(image_widget)
except KeyboardInterrupt:
video.release()
break