Reproducing Python script in R via "reticulate" - python

I am trying to recreate a working python script using RStudio's reticulate package for python. The working script is an adaption of dlib's face detection script. I have it almost working, I think, but I do not know how to enumerate along an object. In the original script, it reads:
from imutils import face_utils
import numpy as np
import imutils
import dlib
import cv2
detector = dlib.get_frontal_face_detector()
predictor = dlib.shape_predictor("path/to/shape_predictor_68_face_landmarks.dat")
image = cv2.imread("path/to/defiant2.jpg")
print(image.shape)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
rects = detector(gray, 1)
for (i, rect) in enumerate(rects):
shape = predictor(gray, rect)
shape = face_utils.shape_to_np(shape)
bb = face_utils.rect_to_bb(rect)
rect = shape[1]
for rect in shape:
print("{} {}".format(*rect))
print("{} {} {} {}".format(*bb))
When I try and recreate this in R to the best of my ability, I hit a roadblock when it is supposed to enumerate along the dlib detector object. Specifically, I get the following error:
library(reticulate)
cv2 <- import('cv2', convert = FALSE)
dlib <- import('dlib', convert = FALSE)
face_utils <- import('imutils.face_utils')
imutils <- import('imutils')
np <- import('numpy')
main <- import_main()
py <- import_builtins()
shape_predictor = 'shape_predictor_68_face_landmarks.dat'
img = 'defiant2.jpg'
detector = dlib$get_frontal_face_detector()
predictor = dlib$shape_predictor(shape_predictor)
image = cv2$imread(img)
gray = cv2$cvtColor(image, cv2$COLOR_BGR2GRAY)
rects = detector$run(gray)
py$enumerate(rects)
Error: attempt to apply non-function
Any help in transferring the code to R would be greatly appreciated. If it helps, I have uploaded the full script files, as well as a test image and the shape predictor landmarks file to Github.

Related

Using Tesseract-OCR in Python to get number from images

I have thousands of scale images that I would like to extract the reading of the scale from each image. However, when using the Tesseract it gives wrong values. I tried several process for the image but still running to same issue. From my understanding so far after defining region of interest in the image, it has to be converted to white text with black background. However, I am new to python, I tried some functions to do so but still running to same issue. Would be appreciated if someone can help me on this one. The following link is for the image, as I couldn't uploaded it here as it is more than 2 MiB:
https://mega.nz/file/fZMUDRbL#tg4Tc2VmGMMdEpnZzt7blxZjVLdlhMci9jll0FLnIGI
import cv2
import pytesseract
import matplotlib.pyplot as plt
import numpy as np
import imutils
## Reading Image File
Filename = 'C:\\Users\\Abdullah\\Desktop\\Scale Reading\\' #File Path For Images
IName = 'Disk_Test_1_09_07-00000_0.tif' # Image Name
Image = cv2.imread(Filename + IName,0)
## Image Processing
Image_Crop = Image[1680:1890, 550:1240] # Define Region of Interest of the image
#cv2.imshow("cropped", Image_Crop) # Show Cropped Image
#cv2.waitKey(0) # Show Cropped Image
Mask = Image_Crop > 10 # Thershold Image to Value of X
Mask = np.array(Mask, dtype=np.uint8)
plt.imshow(Mask, alpha=1) # Set Opacity (Max 1)
ret,Binary = cv2.threshold(Mask,0,255,cv2.THRESH_BINARY)
#plt.imshow(Image_Crop, cmap="gray") # Transform Image to Gray
#plt.show()
plt.imshow(Binary,'gray',vmin=0,vmax=255)
plt.show()
## Number Recognition
pytesseract.pytesseract.tesseract_cmd = r'C:\Program Files\Tesseract-OCR\tesseract.exe' # Call Location of Tesseract-OCR
data = pytesseract.image_to_string(Binary, lang='eng',config='--psm 6')
print(data)
Here is the image after processing

Panda3d rendered window to numpy array

I was following this topic to try to get the buffer data from a camera and save it as a numpy array. Following the topic I reused this code:
base.graphicsEngine.renderFrame()
dr = base.camNode.getDisplayRegion(0)
tex = dr.getScreenshot()
data = tex.getRamImage()
image = np.frombuffer(data,np.uint8)
image.shape = (tex.getYSize(),tex.getXSize(),tex.getNumComponents())
print(image)
However, I get this error:
File "main.py", line 137, in __init__
image = np.frombuffer(data,np.uint8)
AttributeError: 'panda3d.core.ConstPointerToArray_unsigned_char' object has no attribute '__buffer__'
Any advice?
Solved it by changing the original code to the following:
base.graphicsEngine.renderFrame()
dr = base.camNode.getDisplayRegion(0)
tex = dr.getScreenshot()
data = tex.getRamImage()
v = memoryview(data).tolist()
img = np.array(v,dtype=np.uint8)
img = img.reshape((tex.getYSize(),tex.getXSize(),4))
img = img[::-1]
cv2.imshow('img',img)
cv2.waitKey(0)
The image ends up being flipped for whatever reason after reshaping the numpy array hence the 3rd line from the bottom. You should see an identical image of whatever your camera sees when you run this snippet as an accept key or something. Hope this helps someone having the same issues.
I was having trouble with a few bugs on pyrender, so i wanted to use panda3d as a offscreen render, and this was very usefull, expanding on what Masa Hu posted, here is the full example on how to do that:
from direct.showbase.ShowBase import ShowBase
import cv2
import numpy as np
base = ShowBase( windowType='offscreen')
box = base.loader.loadModel("meshes/box.egg")
box.setPos(0,10,0)
box.reparentTo(base.render)
base.graphicsEngine.renderFrame()
dr = base.camNode.getDisplayRegion(0)
tex = dr.getScreenshot()
data = tex.getRamImage()
v = memoryview(data).tolist()
img = np.array(v,dtype=np.uint8)
img = img.reshape((tex.getYSize(),tex.getXSize(),4))
img = img[::-1]
cv2.imshow('img',img)
cv2.waitKey(0)

cv2 treshold does not work correctly on second image

I am new to python and I was playing around with background subtraction to visualize changes in pre and post change images.
I wrote a short and simple script using the cv2 library:
#!/usr/bin/env python
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
#GRAYSCALE ONLY FOR TESTING
#Test with person appearing in image
img1 = cv.imread("images/1.jpg", 0)
img2 = cv.imread("images/2.jpg", 0)
img3 = cv.subtract(img1, img2)
ret,thresh1 = cv.threshold(img3,90,255,cv.THRESH_BINARY)
#Test with satelite image of japan landslide changes after earthquake
jl_before = cv.imread("images/japan_earthquake_before.jpg",0)
jl_after = cv.imread("images/japan_earthquake_after.jpg",0)
jl_subtraction = cv.subtract(jl_before, jl_after)
ret,thresh2 = cv.threshold(img3,20,255,cv.THRESH_BINARY)
images = [img1, img2, thresh1, jl_before, jl_after, thresh2]
titles = ["Image1", "Image2", "Changes", "Japan_Before", "Japan_After", "Japan_Changes" ]
for i in range(6):
plt.subplot(2,3,i+1),plt.imshow(images[i],'gray')
plt.title(titles[i])
plt.xticks([]),plt.yticks([])
plt.show()
The result looks like this:
Why is the mask with changes from the first set of images present in the mask of the second set of images?
I used different variables, thresh1 and thresh2.
Any help would be greatly appreciated as I can't seem to find the problem.
Because you missed a change when copy pasting:
ret,thresh2 = cv.threshold(img3,20,255,cv.THRESH_BINARY)
^^^^

Detect multiple faces using Dlib's face detector using python

The following is the code used to detect single face in a image but the issue is if there are multiple faces in a image it takes only first one. Pls suggest
import caffe, dlib, io
from __future__ import print_function
import os
import matplotlib.pyplot as plt
detector = dlib.get_frontal_face_detector()
img21 = 'group.jpg'
im_name = img21
img = io.imread(os.path.join('./',im_name))
faces=[]
faces= detector(img)
total= len(faces)
print('total faces here :',total)
cropped_face = input_image_cropped[faces[0].top():faces[0].bottom(),
faces[0].left():faces[0].right(), :]
input_image_cropped = caffe.io.load_image(os.path.join('./', im_name))
cropped_face = input_image_cropped[faces[0].top():faces[0].bottom(),
faces[0].left():faces[0].right(), :]
h = faces[0].bottom() - faces[0].top()
w = faces[0].right() - faces[0].left()
age_prediction_cropped = age_net.predict([cropped_face])
print('\n\t predicted age (Dlib-cropped image):',
age_prediction_cropped[0].argmax())
plt.show()
FYI:
i stripped other parts of the code which is not required.
I gone thru the below link but i could not run the loop for all the detected faces ? pls suggest how can i run the loop for all detected faces.
http://dlib.net/face_detector.py.html
With the following change the issue is resolved
for i, d in enumerate(faces):
cropped_face = input_image_cropped[ d.top():d.bottom(), d.left():d.right(), :]
input_image_cropped = caffe.io.load_image(os.path.join('./', im_name))
cropped_face = input_image_cropped[d.top():d.bottom(), d.left():d.right(), :]

Knearest() function Not Working in opencv 2.4.8 and python 2.7.5

I am using OpenCV 2.4.8 and python 2.7.5 in Ubuntu 14.04
When I call
knn=cv2.KNearest()
I get an error saying
knn=cv2.KNearest() AttributeError: 'module' object has no attribute 'KNearest'
How can I resolve it?
Full Code is here
import cv2
import numpy as np
####### training part ###############
samples = np.loadtxt('generalsamples.data',np.float32)
responses = np.loadtxt('generalresponses.data',np.float32)
responses = responses.reshape((responses.size,1))
model = cv2.KNearest()
model.train(samples,responses)
####################### testing part
im = cv2.imread('training_images/number1.jpg')
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
image,contours,hierarchy = cv2.findContours(thresh,cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)
for cnt in contours:
if cv2.contourArea(cnt)>50:
[x,y,w,h] = cv2.boundingRect(cnt)
if h>28:
cv2.rectangle(im,(x,y),(x+w,y+h),(0,255,0),2)
roi = thresh[y:y+h,x:x+w]
roismall = cv2.resize(roi,(10,10))
roismall = roismall.reshape((1,100))
roismall = np.float32(roismall)
retval, results, neigh_resp, dists = model.find_nearest(roismall, k = 1)
string = str(int((results[0][0])))
cv2.putText(out,string,(x,y+h),0,1,(0,255,0))
cv2.imshow('im',im)
cv2.imshow('out',out)
cv2.waitKey(0) & 0 x FF
That is the correct way to call KNearest(), so you are doing something else wrong.
Here is a complete working example of using k-Nearest Neighbours taken from [here].
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Feature set containing (x,y) values of 25 known/training data
trainData = np.random.randint(0,100,(25,2)).astype(np.float32)
# Labels each one either Red or Blue with numbers 0 and 1
responses = np.random.randint(0,2,(25,1)).astype(np.float32)
# Take Red families and plot them
red = trainData[responses.ravel()==0]
plt.scatter(red[:,0],red[:,1],80,'r','^')
# Take Blue families and plot them
blue = trainData[responses.ravel()==1]
plt.scatter(blue[:,0],blue[:,1],80,'b','s')
plt.show()
newcomer = np.random.randint(0,100,(1,2)).astype(np.float32)
plt.scatter(newcomer[:,0],newcomer[:,1],80,'g','o')
knn = cv2.KNearest()
knn.train(trainData,responses)
ret, results, neighbours ,dist = knn.find_nearest(newcomer, 3)
print "result: ", results,"\n"
print "neighbours: ", neighbours,"\n"
print "distance: ", dist
plt.show()
If that doesn't work, then you have larger problems.
I have solved this problem. The problem was in opencv version. That's why it was not recognizing KNN function. I have installed opencv 2.4.10 and it works fine. Thank you all.

Categories