How to get points coordinate position in the face landmark detection program of dlib? - feature-detection

There is one example python program in dlib to detect the face landmark position.
face_landmark_detection.py
This program detect the face feature and denote the landmarks with dots and lines in original photo.
I wonder if it is possible to obtain each points' coordinate position. Like a(10, 25). 'a' denotes corner of the mouth.
After slightly modifying the program to process one picture at one time, I try to print out the value of dets and shape without success.
>>>print(dets)
<dlib.dlib.rectangles object at 0x7f3eb74bf950>
>>>print(dets[0])
[(1005, 563) (1129, 687)]
The arguments to denote face landmark points and the datatype of arguments still remain unknown.
And here is the simplified code
import dlib
from skimage import io
#shape_predictor_68_face_landmarks.dat is the train dataset in the same directory
predictor_path = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
win = dlib.image_window()
#FDT.jpg is the picture file to be processed in the same directory
img = io.imread("FDT.jpg")
win.set_image(img)
dets = detector(img)
print("Number of faces detected: {}".format(len(dets)))
for k, d in enumerate(dets):
print("Detection {}: Left: {} Top: {} Right: {} Bottom: {}".format(
k, d.left(), d.top(), d.right(), d.bottom()))
# Get the landmarks/parts for the face in box d.
shape = predictor(img, d)
#print(shape)
print("Part 0: {}, Part 1: {} ...".format(shape.part(0),
shape.part(1)))
# Draw the face landmarks on the screen.
win.add_overlay(shape)
win.add_overlay(dets)
dlib.hit_enter_to_continue()
---------------------------update on 3.10.2016---------------------------
Today, I remember the help() method in python and have a trial with it.
>>>help(predictor)
Help on shape_predictor in module dlib.dlib object:
class shape_predictor(Boost.Python.instance)
| This object is a tool that takes in an image region containing
some object and outputs a set of point locations that define the pose
of the object. The classic example of this is human face pose
prediction, where you take an image of a human face as input and are
expected to identify the locations of important facial landmarks such
as the corners of the mouth and eyes, tip of the nose, and so forth.
In the original code, variable shape is the output of predictor method.
>>>help(shape)
The description of shape
class full_object_detection(Boost.Python.instance)
| This object represents the location of an object in an image along
with the positions of each of its constituent parts.
----------------------------------------------------------------------
| Data descriptors defined here:
|
| num_parts
| The number of parts of the object.
|
| rect
| The bounding box of the parts.
|
| ----------------------------------------------------------------------
It seems that variable shape is related with points coordinate position.
>>>print(shape.num_parts)
68
>>>print(shape.rect)
[(1005, 563) (1129, 687)]
I assume that there are 68 denoted face landmark points.
>>> print(shape.part(68))
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: Index out of range
>>> print(shape.part(65))
(1072, 645)
>>> print(shape.part(66))
(1065, 647)
>>> print(shape.part(67))
(1059, 646)
If it is true. The remained problem is that which part is responding to which face landmark point.

I slightly modified the code.
import dlib
import numpy as np
from skimage import io
predictor_path = "shape_predictor_68_face_landmarks.dat"
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor(predictor_path)
img = io.imread("FDT.jpg")
dets = detector(img)
#output face landmark points inside retangle
#shape is points datatype
#http://dlib.net/python/#dlib.point
for k, d in enumerate(dets):
shape = predictor(img, d)
vec = np.empty([68, 2], dtype = int)
for b in range(68):
vec[b][0] = shape.part(b).x
vec[b][1] = shape.part(b).y
print(vec)
Here is the output
[[1003 575]
[1005 593]
[1009 611]
[1014 627]
[1021 642]
[1030 655]
[1041 667]
[1054 675]
[1069 677]
[1083 673]
[1095 664]
[1105 651]
[1113 636]
[1120 621]
[1123 604]
[1124 585]
[1124 567]
[1010 574]
[1020 570]
[1031 571]
[1042 574]
[1053 578]
[1070 577]
[1081 572]
[1092 568]
[1104 566]
[1114 569]
[1063 589]
[1063 601]
[1063 613]
[1063 624]
[1050 628]
[1056 630]
[1064 632]
[1071 630]
[1077 627]
[1024 587]
[1032 587]
[1040 586]
[1048 588]
[1040 590]
[1031 590]
[1078 587]
[1085 585]
[1093 584]
[1101 584]
[1094 588]
[1086 588]
[1045 644]
[1052 641]
[1058 640]
[1064 641]
[1070 639]
[1078 640]
[1086 641]
[1080 651]
[1073 655]
[1066 656]
[1059 656]
[1052 652]
[1048 645]
[1059 645]
[1065 646]
[1071 644]
[1083 642]
[1072 645]
[1065 647]
[1059 646]]
And there is another open source project OpenFace, which is based on dlib and describes each point's correlating part in face.
The url of describing image

Related

Detecting and removing blank area in image

I have a collection of 35.000 greyscale scans of different paper-based forms. Some of the paper forms are in landscape and some in portrait orientation. Some of the landscape forms were scanned in portrait mode by mistake. This results in a scan, that has whitespace in the lower two thirds (approximately). Of course there is some noise in the whitespace.
What I need to do is to remove the whitespace from the portrait scan and convert it to a landscape scan. That should be pretty simple, but I'm obviously new to image processing.
So any help would be highly appreciated. Sorry for not being able to post an example, because the scans contain personal medical data.
EDIT:
from skimage import io
from skimage.util import crop
import numpy as np
image = io.imread(convert_image_path + filename)
crop_image = crop(image, ( image.shape[0]/5, image.shape[0]), ((0, image.shape[1])), (0,image.shape[2]))
and the result is:
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-21-6cc7c0d534bf> in <module>
4
5 image = io.imread(convert_image_path + filename)
----> 6 crop_image = crop(image, ( image.shape[0]/5, image.shape[0]), ((0, image.shape[1])), (0,image.shape[2]))
/usr/local/lib/python3.7/site-packages/skimage/util/arraycrop.py in crop(ar, crop_width, copy, order)
58 for i, (a, b) in enumerate(crops))
59 if copy:
---> 60 cropped = np.array(ar[slices], order=order, copy=True)
61 else:
62 cropped = ar[slices]
ValueError: Non-string object detected for the array ordering. Please pass in 'C', 'F', 'A', or 'K' instead
I'll try to answer to what I think are your three main questions.
How to slice an image
How to rotate an image 90 degrees.
How to detect large white areas.
Inputs
I generated the following input
using:
import numpy as np
from skimage import io
portrait = np.full(shape=(250, 150), fill_value=255, dtype=np.uint8)
portrait[:200, :] = 0
io.imsave("portrait.png", portrait)
How to slice
For slicing we can directly use numpy, which has a coordinate system starting in the left top, with row, column order (y, x).
In order to slice the bottom part of the image we have to select the top part, by using [:200], which take all the rows above the 200. (dropping the last 50 white rows).
from skimage import io
portrait = io.imread("portrait.png")
sliced = portrait[:200]
io.imsave("portrait slice.png", sliced)
How to rotate
For rotation there is a build in method rot90 in numpy.
import numpy as np
from skimage import io
portrait = io.imread("portrait.png")
rotated = np.rot90(portrait, k=-1) # Rotate clockwise, k=1, rotate counter clockwise
io.imsave("portrait rotated.png", rotated)
How to detect white areas
For detecting large white areas, you can look at the average values in a row and column. Based on that you can decide whether there is enough white to indicate it as a blank region.
import numpy as np
from itertools import groupby, count
from skimage import io
portrait = io.imread("portrait.png")
# We take the average value for every row.
rows = np.average(portrait, axis=1)
# This returns the row indices that have a gray value higher than 240
white_rows = np.squeeze(np.argwhere(rows > 240), axis=-1)
# This locates the groups of consecutive rows that are largely white
groups = groupby(white_rows, key=lambda item, c=count(): item - next(c))
for index, group in groups:
white_region = list(group)
# Only slice regions that contains at least so many largely white rows.
if len(white_region) > 30:
slicing = [white_region[0], white_region[-1]]
print(slicing)
Example output:
[200, 249]
So now we know where there is a large white area in the image. In your case you might want to verify that the region is exclusively in the bottom part of the image. This can be done by filtering the white rows on low values.
white_rows = white_rows[white_rows > 150]
This means that the white rows have to be past the 150th pixel row.
Extra
To detect if the image is in portrait or not you can use the image shape
portrait = image.shape[0] > image.shape[1]

How can I refresh Trimesh(Pyglet) viewer to see my mesh(stl) rotation and interupt this visualisation after an angular condition?

After long hours to search by myself a solution to my question, I am here to find some help so that, I hope, someone could help me to unfreeze my actual situation. So if there is any specialist or nice "Python Guru" who has some time to give me a hand on it, here is the context :
I am working on a mesh manipulation script thanks to the wonderful Trimesh library on Python 3.6 and I would like, while applying some matrix rotation transformation, to refresh the mesh visualisation in order to see the real time rotation evolution of the mesh.
Without success, I did some try following the hereinbelow script found on the Trimesh GitHub but I am not able to stop it without clicking on the upper right "closing cross". Here is the original code:
"""
view_callback.py
------------------
Show how to pass a callback to the scene viewer for
easy visualizations.
"""
import time
import trimesh
import numpy as np
def sinwave(scene):
"""
A callback passed to a scene viewer which will update
transforms in the viewer periodically.
Parameters
-------------
scene : trimesh.Scene
Scene containing geometry
"""
# create an empty homogenous transformation
matrix = np.eye(4)
# set Y as cos of time
matrix[1][3] = np.cos(time.time()) * 2
# set Z as sin of time
matrix[2][3] = np.sin(time.time()) * 3
# take one of the two spheres arbitrarily
node = s.graph.nodes_geometry[0]
# apply the transform to the node
scene.graph.update(node, matrix=matrix)
if __name__ == '__main__':
# create some spheres
a = trimesh.primitives.Sphere()
b = trimesh.primitives.Sphere()
# set some colors for the balls
a.visual.face_colors = [255, 0, 0, 255]
b.visual.face_colors = [0, 0, 100, 255]
# create a scene with the two balls
s = trimesh.Scene([a, b])
# open the scene viewer and move a ball around
s.show(callback=sinwave)
And here is my try to integrate a matrix rotation transformation (to apply rotation on the imported mesh) to see the evolution.
But the rotation is not smooth (the animation is crenellated) and I am not able to stop it automatically lets say after a 97° rotation on z. (And the code is based on time while I would like it to be based on angular position).
from pathlib import Path
import pandas as pd
import time
import xlsxwriter
import numpy as np
import trimesh
from trimesh import transformations as trf
# Actual directory loading and stl adress saving
actual_dir = Path(__file__).resolve().parent
stl = Path(actual_dir/"Belt_Bearing_Gear.stl")
mesh = trimesh.load(f"{stl}")
def R_matrix(scene):
u= 0
o= 0
t= time.time()
time.sleep(0.1)
rotation = (u, o, t)
# Angle conversion from degres to radian
def trig(angle):
r = np.deg2rad(angle)
return r
alpha = trig(rotation[0])
beta = trig(rotation[1])
gamma = trig(rotation[2])
origin, xaxis, yaxis, zaxis = [0, 0, 0], [1, 0, 0], [0, 1, 0], [0, 0, 1]
Rx = trf.rotation_matrix(alpha, xaxis)
Ry = trf.rotation_matrix(beta, yaxis)
Rz = trf.rotation_matrix(gamma, zaxis)
R = trf.concatenate_matrices(Rx, Ry, Rz)
R2=R[:3,:3]
# The rotation matrix is applyed to the mesh
mesh.vertices = np.matmul(mesh.vertices,R2)
# apply the transform to the node
s = trimesh.Scene([mesh])
scene.graph.update(s, matrix=R)
if __name__ == '__main__':
# set some colors for the mesh and the bounding box
mesh.visual.face_colors = [102, 255, 255, 255]
# create a scene with the mesh and the bounding box
s = trimesh.Scene([mesh])
liste=list(range(1,10))
# open the scene viewer and move a ball around
s.show(callback=R_matrix)
All your ideas and suggestions are welcome since I am a young Python beginner :)
Thanks in advance for your help,
Warm regards,
RV

Checking whether a list of points lie within a multipolygon (Python)

I am trying to check whether a list of points (which are stored in df.Coords) are found inside my shapefile (multipolygon). I wrote a code below, however, I realised that python only reads in the coordinates of my final layer of my multipolygon.
import shapefile
from shapely.geometry import shape, Point
# read your shapefile
r = shapefile.Reader("C:\\filename.shp")
# get the shapes
shapes = r.shapes()
# build a shapely polygon from your shape
hold = []
for k in range(len(shapes)-1):
polygon = shape(shapes[k])
hold.append(polygon)
for x in df.Coords:
if polygon.contains(Point(x)):
hold.append(x)
I tried to search for some code on stackoverflow (reference: https://gis.stackexchange.com/questions/208546/check-if-a-point-falls-within-a-multipolygon-with-python/208574) and edited it (as shown below). However, I think I have edited it incorrectly.
from shapely.geometry import Polygon, Point, MultiPolygon
import shapefile
polygon = shapefile.Reader("C:\\filename.shp")
polygon = polygon.shapes()
shpfilePoints = [ shape.points for shape in polygon ]
#print(shpfilePoints)
polygons = shpfilePoints
hold = []
for polygon in polygons:
poly = Polygon(polygon)
hold.append(poly)
for x in hold:
for y in df.Coords:
if x.contains(Point(y)):
hold.append(y)
print('hold',hold)
How can I check if my list of points (df.Coords) lie within my multipolygon (with 26 layers?)

How do I discriminate two different type of abnormalities in curvature of the object?

I have been working on a project that require finding defect in onions. The second image that's attached shows an abnormal onion. You can see that the onion is made-up of two smaller onion twins. What's interesting is that human eye can easily detect whats wrong with the structure.
One can do an structural analysis and can observe that a normal onion has almost smooth curvature while an abnormal one doesn't. Thus quite simply I want to build a classification algorithm based on the edges of the object.
However there are times when the skin of onion makes the curve irregular. See the image, there's a small part of skin that's outside the actual curvature. I want to discriminate the bulged part due to the skin vs the deformities produced at the point where the two subsection meet and then reconstruct the contour of object for further analysis .
Is there a mathematical thing that would help me here given the fact that I have majority of the points that makes the outer edge of onion including the two irregularities?
[
See the code below:
import cv2
import numpy as np
import sys
cv2.ocl.setUseOpenCL(False)
cv2.namedWindow('test', cv2.WINDOW_NORMAL)
cv2.namedWindow('orig', cv2.WINDOW_NORMAL)
cv2.resizeWindow('test', 600,600)
cv2.resizeWindow('orig', 600,600)
image = cv2.imread('./buffer/crp'+str(sys.argv[1])+'.JPG')
tim = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
hsv_image = cv2.cvtColor(image,cv2.COLOR_BGR2HSV)
frame_threshed = cv2.inRange(hsv_image, np.array([70,0,0],np.uint8),
np.array([140,255,255],np.uint8))
canvas = np.zeros(image.shape, np.uint8)
framhreshed=cv2.threshold(frame_threshed,10,255,cv2.THRESH_BINARY_INV)
kernel = np.ones((3,3),np.uint8)
frame_threshed = cv2.erode(frame_threshed,kernel,iterations = 1)
kernel = np.ones((5,5),np.uint8)
frame_threshed = cv2.erode(frame_threshed,kernel,iterations = 1)
kernel = np.ones((7,7),np.uint8)
frame_threshed = cv2.erode(frame_threshed,kernel,iterations = 1)
_, cnts, hierarchy = cv2.findContours(frame_threshed.copy(),
cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts= sorted(cnts, key=cv2.contourArea, reverse=True)
big_contours = [c for c in cnts if cv2.contourArea(c) > 100000]
for cnt in big_contours:
perimeter = cv2.arcLength(cnt,True)
epsilon = 0.0015*cv2.arcLength(cnt,True)
approx = cv2.approxPolyDP(cnt,epsilon,True)
# print(len(approx))
hull = cv2.convexHull(cnt,returnPoints = False)
# try:
defects = cv2.convexityDefects(cnt,hull)
for i in range(defects.shape[0]):
s,e,f,d = defects[i,0]
start = tuple(cnt[s][0])
end = tuple(cnt[e][0])
far = tuple(cnt[f][0])
cv2.line(canvas,start,end,[255,0,0],2)
cv2.circle(canvas,far,5,[255,255,255],-1)
cv2.drawContours(image, [approx], -1, (0, 0, 255), 5)
cv2.drawContours(canvas, [approx], -1, (0, 0, 255), 5)
cv2.imshow('orig',image)
cv2.imshow('test',canvas)
cv2.waitKey(0)
cv2.destroyAllWindows()
I would suggest you to try HuMoments since you already have extracted the shape of your objects. It would allow you to calculate a distance between two shapes, so basically between your abnormal onion and a reference onion.
The Hu Moments shape descriptor is available for Python using OpenCV. If image is binary, you can use it like this :
# Reference image
shapeArray1 = cv2.HuMoments(cv2.moments(image1)).flatten()
# Abnormal image
shapeArray2 = cv2.HuMoments(cv2.moments(image2)).flatten()
# Calculation of distance between both arrays
# Threshold based on the distancce
# Classification as abnormal or normal
MatchShapes could do the job too. It takes two binary images of contours to return a float that evaluate the distance between both.
Python: cv.MatchShapes(object1, object2, method, parameter=0) → float
More details
So when an onion shape is detected as abnormal, you would have to fill this shape and apply some binary morphology to erase the imperfection and extract the shape without imperfection.
Fill your shape
Apply an opening (erosion followed by dilatation) with a disk structural element to get rid of the irregularities
Extract the contours again
You should have a form without your irregularities. If not, go back to step 2 and change the size of the structural element
OK so if you look at the first two pictures of your onions you can see that they have a circular shape (except the peel peaks) and the "defect" one has more of an oval shape. What you could try is to find your contour (after you apply image transformation of course) and determine its center points. Then you could measure the distance from the center of the contour to each point of the contour. You can do it using scipy (ckd.tree() and tree.query()) or simply by mathematical formula for distance between two points sqrt(x2-x1)^2+(y2-y1)^2. Then you can say that if some number of points are out of bounds it is still an OK onion but if there are a lot of points out of bounds then it is a defective onion. I drew two example images just for the sake of demonstration.
Example in code:
import cv2
import numpy as np
import scipy
from scipy import spatial
img = cv2.imread('oniond.png')
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(gray_image,180,255,cv2.THRESH_BINARY_INV)
im2, cnts, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
cnt = max(cnts, key=cv2.contourArea)
list_distance = []
points_minmax = []
M = cv2.moments(cnt)
cX = int(M["m10"] / M["m00"])
cY = int(M["m01"] / M["m00"])
center = (cX, cY)
for i in cnt:
tree = spatial.cKDTree(i)
mindist, minid = tree.query(center)
list_distance.append(mindist)
if float(mindist) < 100:
points_minmax.append(i)
elif float(mindist) > 140:
points_minmax.append(i)
else:
pass
reshape = np.reshape(list_distance, (-1,1))
under_min = [i for i in list_distance if i < 100]
over_max = [i for i in list_distance if i > 140]
for i in points_minmax:
cv2.line(img,center,(i[0,0],i[0,1]),(0,0,255),2)
if len(over_max) > 50:
print('defect')
print('distances over maximum: ', len(over_max))
print('distances over minimum: ', len(under_min ))
elif len(under_min ) > 50:
print('defect')
print('distances over maximum: ', len(over_max))
print('distances over minimum: ', len(under_min ))
else:
print('OK')
print('distances over maximum: ', len(over_max))
print('distances over minimum: ', len(under_min ))
cv2.imshow('img', img)
Result:
OK
distances over maximum: 37
distance over minimum: 0
The output shows that there are 37 points out of bounds (red color) but the onion is still OK.
Result 2:
defect
distances over maximum: 553
distances over minimum: 13
And here you can see that there are more points out of bounds (red color) and the onion is not OK.
Hope this gives at least an idea on how to solve your problem. Cheers!

Integrate k-nearest-neighbors (KNN) algorithm for face recognition in real time with OpenCV

I'm using the face_recognition library for Python and I'm trying to change the KNN algorithm to run with OpenCV in real time. For that I "merged" two other algorithms provided by the library author (algorithm1, algorithm2).
(Edited: Now it shows the frame until it detect some face, then it crashes)
What I tried so far:
import numpy as np
import cv2
import face_recognition
import pickle
def predict(frame, knn_clf=None, model_path=None, distance_threshold=0.6):
"""
Recognizes faces in given image using a trained KNN classifier
:param knn_clf: (optional) a knn classifier object. if not specified, model_save_path must be specified.
:param model_path: (optional) path to a pickled knn classifier. if not specified, model_save_path must be knn_clf.
:param distance_threshold: (optional) distance threshold for face classification. the larger it is, the more chance
of mis-classifying an unknown person as a known one.
:return: a list of names and face locations for the recognized faces in the image: [(name, bounding box), ...].
For faces of unrecognized persons, the name 'unknown' will be returned.
"""
if knn_clf is None and model_path is None:
raise Exception("Must supply knn classifier either thourgh knn_clf or model_path")
# Load a trained KNN model (if one was passed in)
if knn_clf is None:
with open(model_path, 'rb') as f:
knn_clf = pickle.load(f)
# find face locations from frame
X_face_locations = face_recognition.face_locations(frame)
# If no faces are found in the image, return an empty result.
if len(X_face_locations) == 0:
return []
# Find encodings for faces in the frame
faces_encodings = face_recognition.face_encodings(frame, known_face_locations=X_face_locations)
# Use the KNN model to find the best matches for the test face
closest_distances = knn_clf.kneighbors(faces_encodings, n_neighbors=1)
are_matches = [closest_distances[0][i][0] <= distance_threshold for i in range(len(X_face_locations))]
# Predict classes and remove classifications that aren't within the threshold
return [(pred, loc) if rec else ("unknown", loc) for pred, loc, rec in zip(knn_clf.predict(faces_encodings), X_face_locations, are_matches)]
def show_labels_on_webcam(RGBFrame, predictions):
"""
Shows the face recognition results visually.
:param img_path: path to image to be recognized
:param predictions: results of the predict function
:return:
"""
frame = RGBFrame
for name, (top, right, bottom, left) in predictions:
# Scale back up face locations since the frame we detected in was scaled to 1/4 size
top *= 4
right *= 4
bottom *= 4
left *= 4
# Draw a box around the face
print (frame.shape)
print (frame.dtype)
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
# Draw a label with a name below the face
cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)
# Display the resulting image
cv2.imshow('Video', frame)
# Get a reference to webcam #0 (the default one)
video_capture = cv2.VideoCapture(0)
while True:
# Grab a single frame of video
ret, frame = video_capture.read()
# Resize frame of video to 1/4 size for faster face recognition processing
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
# Convert the image from BGR color (which OpenCV uses) to RGB color (which face_recognition uses)
rgb_small_frame = small_frame[:, :, ::-1]
predictions = predict(rgb_small_frame, model_path="trained_knn_model_1.clf")
# Display results overlaid on webcam video
print (rgb_small_frame.shape)
print (rgb_small_frame.dtype)
show_labels_on_webcam(rgb_small_frame, predictions)
# Hit 'q' on the keyboard to quit!
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# Release handle to the webcam
video_capture.release()
cv2.destroyAllWindows()
The error I'm getting:
Traceback (most recent call last):
File "withOpenCV.py", line 91, in <module>
show_labels_on_webcam(rgb_small_frame, predictions)
File "withOpenCV.py", line 62, in show_labels_on_webcam
cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)
TypeError: Layout of the output array img is incompatible with cv::Mat (step[ndims-1] != elemsize or step[1] != elemsize*nchannels)
If you have any suggestions or see what I'm missing, please let me know! Thanks in advance!
I solved the error by changing the show_labels_on_webcam(rgb_small_frame, predictions) by show_labels_on_webcam(frame, predictions). Thanks to #api55 for the hint!

Resources