Tracking black objects live streaming - python-2.7

I'm trying to make a project that tracks the black objects on the ground with a harsh desert sunny environment and I tried to make some trials but it doesn't work. I tried converting the black pixels in the image to Red because the Red pixels is easy to track (higher intensity) but it doesn't result in what I want. I tried inverting the image (converting the black to white and white to black) but it doesn't give the desired result either. So any ideas?
Here is the code:
import cv2
import numpy as np
import os
from matplotlib import pyplot as plt
cap = cv2.VideoCapture(0)
while cap.isOpened():
ret,frame = cap.read()
warp = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
ORANGE_MIN = np.array([40, 40, 60], np.uint8)
ORANGE_MAX = np.array([50, 70, 80], np.uint8)
hsv_img = cv2.cvtColor(frame, cv2.COLOR_BGR2HSV)
Conv_hsv_Gray = cv2.cvtColor(hsv_img, cv2.COLOR_BGR2GRAY)
imf = np.float32(Conv_hsv_Gray) / 255.0 # float conversion/scale
Desc = cv2.dct(imf)
sub_to = Desc[0, 0]
print sub_to
result_frame = Desc - sub_to
Fitr = cv2.blur(result_frame, (1, 1))
Filter2 = cv2.GaussianBlur(Desc, (1, 1), 0)
iddt1 = cv2.idct(Fitr)
iddt2 = cv2.idct(Filter2)
framethreshed = cv2.inRange(hsv_img, ORANGE_MIN, ORANGE_MAX)
ret, mask = cv2.threshold(Conv_hsv_Gray, 100, 150, cv2.THRESH_BINARY)
mask_inv = cv2.bitwise_not(warp)
mask = cv2.erode(mask, None, iterations=2)
mask = cv2.dilate(mask, None, iterations=2)
res = cv2.bitwise_and(iddt1, iddt1, mask=mask)
cv2.imwrite('output2.jpg', framethreshed)
cv2.imshow("imgOriginal(1)", frame) # show windows
cv2.imshow("Masking res(3)", res) # show windows
cv2.imshow("mask_inv)", mask_inv) # show windows
if cv2.waitKey(60) & 0xFF == ord('q'):
break
cap.release()

Related

Why doesn't an array made from a PIL draw.text() image show properly in Matplotlib?

I'd like to understand why, when I convert the PIL image imageRGB to a float array arrayRGB_f and use matplotlib's imshow() without a cmap it looks either black, or strange and unreadable, even though PIL's imageRGB.show() looks fine, and each of the individual r, g, b channels shown with cmap='gray' look okay as well.
I have workarounds, but I just don't understand why this happens.
matplotlib.__version__ returns '2.0.2' and I'm using MacOS with an Anaconda installation.
See this answer for more on the conversion of a ttf rendering to a 1bit.
fyi the output of the print statements are:
float64 (41, 101, 3)
int64 (41, 101, 3)
int64 (41, 101)
int64 (41, 101)
fontname = 'default'
imageRGB.show()
plt.imshow()
fontname = 'Arial Unicode.ttf'
imageRGB.show()
plt.imshow()
font = ImageFont.truetype(fontname, 20)
imageRGB.show()
plt.imshow()
from PIL import Image, ImageDraw, ImageFont
import numpy as np
import matplotlib.pyplot as plt
# fontname = 'Arial Unicode.ttf'
fontname = 'default'
if fontname == 'default':
font = ImageFont.load_default()
else:
font = ImageFont.truetype(fontname, 12)
string = "Hello " + fontname[:6]
ww, hh = 101, 41
threshold = 80 # https://stackoverflow.com/a/47546095/3904031
imageRGB = Image.new('RGB', (ww, hh))
draw = ImageDraw.Draw(imageRGB)
image8bit = draw.text((10, 12), string, font=font,
fill=(255, 255, 255, 255)) # R, G, B alpha
image8bit = imageRGB.convert("L")
image1bit = image8bit.point(lambda x: 0 if x < threshold else 1, mode='1') # https://stackoverflow.com/a/47546095/3904031
arrayRGB = np.array(list(imageRGB.getdata())).reshape(hh, ww, 3)
arrayRGB_f = arrayRGB.astype(float)
array8bit = np.array(list(image8bit.getdata())).reshape(hh, ww)
array1bit = np.array(list(image1bit.getdata())).reshape(hh, ww)
for a in (arrayRGB_f, arrayRGB, array8bit, array1bit):
print a.dtype, a.shape
imageRGB.show()
if True:
plt.figure()
a = arrayRGB_f
plt.subplot(2, 2, 1)
plt.imshow(a) # , interpolation='nearest', cmap='gray',
for i in range(3):
plt.subplot(2, 2, 2+i)
plt.imshow(a[:, :, i], cmap='gray')
plt.suptitle('arrayRGB_f, fontname = ' + fontname)
plt.show()
I can't find an ideal duplicate so I'll post an answer.
As #ImportanceOfBeingErnest mentions when .imshow() is given an n x m x 3 or n x m x 4 array, it is expecting a normalized array between 0.0 and 1.0.
Best way to do this is:
arrayRGB_f = arrayRGB.astype(float)/255.
though this seems to work as well:
arrayRGB_f = arrayRGB.astype(float)
arrayRGB_f = arrayRGB_f / arrayRGB_f.max()
For longer discussions, see this and this.

Dataset creator with OpenCV and Python error

OS : Ubuntu 17.10
I am trying this code to create a dataset on face detection using Python2.7 and Open CV (installed with pip)
import cv2
import numpy as np
cam = cv2.VideoCapture(0)
detector = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
Id = raw_input('enter your id')
sampleNum = 0
while True:
ret, img = cam.read()
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
faces = detector.detectMultiScale(gray, 1.3, 5)
for (x, y, w, h) in faces:
cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
#incrementing sample number
sampleNum = sampleNum+1
#saving the captured face in the dataset folder
cv2.imwrite("dataSet/User."+Id +'.'+ str(sampleNum) + ".jpg", gray[y:y+h,x:x+w])
cv2.imshow('frame', img)
#wait for 100 miliseconds
if cv2.waitKey(100) & 0xFF == ord('q'):break
# break if the sample number is morethan 20
elif sampleNum > 20: break
cam.release()
cv2.destroyAllWindows()
But I am getting following error
Traceback (most recent call last):
File "/home/anushi/face/datasetCreator.py", line 10, in <module>
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
error: /io/opencv/modules/imgproc/src/color.cpp:10638: error: (-215) scn == 3 || scn == 4 in function cvtColor
As the comments correctly mention, one possible cause is that the image is empty (not captured properly). Another possibility is that the image is not a color image.
You can add
cv2.imshow('frame', img)
Before
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
and see what the captured image looks like.
The rest of the code looks fine.

Python // How to get a rectangle around the target object using the features extracted by SIFT in OpenCV

Here is my code:
import numpy as np
import cv2
from matplotlib import pyplot as plt
from scipy import misc
import matplotlib.pyplot as plt
MIN_MATCH_COUNT = 10
img1 = cv2.imread('Screenshot_2.png',0)
img2 = cv2.imread('Screenshot_12.png',0)
# Initiate SIFT detector
sift = cv2.xfeatures2d.SIFT_create()
# find the keypoints and descriptors with SIFT
kp1, des1 = sift.detectAndCompute(img1,None)
kp2, des2 = sift.detectAndCompute(img2,None)
FLANN_INDEX_KDTREE = 0
index_params = dict(algorithm = FLANN_INDEX_KDTREE, trees = 5)
search_params = dict(checks = 50)
flann = cv2.FlannBasedMatcher(index_params, search_params)
matches = flann.knnMatch(des1,des2,k=2)
good = []
for m,n in matches:
if m.distance < 0.7*n.distance:
good.append(m)
print good
if len(good)>MIN_MATCH_COUNT:
src_pts = np.float32([ kp1[m.queryIdx].pt for m in good ]).reshape(-1,1,2)
dst_pts = np.float32([ kp2[m.trainIdx].pt for m in good ]).reshape(-1,1,2)
M, mask = cv2.findHomography(src_pts, dst_pts, cv2.RANSAC,5.0)
matchesMask = mask.ravel().tolist()
h,w = img1.shape
pts = np.float32([ [0,0],[0,h-1],[w-1,h-1],[w-1,0] ]).reshape(-1,1,2)
dst = cv2.perspectiveTransform(pts,M)
img2 = cv2.polylines(img2,[np.int32(dst)],True,255,3, cv2.LINE_AA)
else:
print "Not enough matches are found - %d/%d" % (len(good),MIN_MATCH_COUNT)
matchesMask = None
draw_params = dict(matchColor = (0,255,0), # draw matches in green color
singlePointColor = None,
matchesMask = matchesMask, # draw only inliers
flags = 2)
img3 = cv2.drawMatches(img1,kp1,img2,kp2,good,None,**draw_params)
plt.imshow(img3, 'gray'),plt.show()
I would like to trace with OpenCV a rectangle of my detected objects with this method, but I do not know how start for get what I want.
I found nowhere to solve my question with Python
Did you have any advice to give me to carry out my project?:(
Just get src_pts where mask==1 and find min_X, min_Y, max_X, max_Y for rectangle onto Source Image.
Below is the code I have tried..
pts = src_pts[mask==1]
min_x, min_y = np.int32(pts.min(axis=0))
max_x, max_y = np.int32(pts.max(axis=0))
Here you got up-left point as (min_x, min_y) and bottom_right point as (max_x, max_y). Below code is for diplaying bounding box on originalImage.
cv2.rectangle(originalImage,(min_x, min_y), (max_x,max_y), 255,2)
plt.imshow(originalImage, cmap='gray')

How to save images to a server folder via sockets using python and opencv?

I would like to know how to save images captured by Opencv, in a directory created by code that should stay on the server ...**
import cv2, sys, numpy, os
haar_file = 'haarcascade_frontalface_default.xml'
datasets = 'datasets' #All the faces data will be present this folder
sub_data = raw_input ('digite o seu nome') #These are sub data sets of folder, for my faces I've used my name
path = os.path.join(datasets, sub_data)
if not os.path.isdir(path):
os.mkdir(path)
(width, height) = (130, 100) # defining the size of images
face_cascade = cv2.CascadeClassifier(haar_file)
webcam = cv2.VideoCapture(0) #'0' is use for my webcam, if you've any other camera attached use '1' like this
# The program loops until it has 100 images of the face.
count = 1
while count < 101:
(_, im) = webcam.read()
gray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
faces = face_cascade.detectMultiScale(gray, 1.3, 4)
for (x,y,w,h) in faces:
cv2.rectangle(im,(x,y),(x+w,y+h),(255,0,0),2)
face = gray[y:y + h, x:x + w]
face_resize = cv2.resize(face, (width, height))
cv2.imwrite('%s/%s.png' % (path,count), face_resize)
count += 1
cv2.imshow('OpenCV', im)
key = cv2.waitKey(10)
if key == 27:
break

Is there a support for BackgroundSubtractorMOG2 in python opencv

Is there a Python binding for BackgroundSubtractorMOG2, cpp apparently has.
I was thinking that there is compatibility between python version of
openCV and cpp version.
The OpenCV 2.x API gives you a Python binding for BackgroundSubtractorMOG, just check this web
http://docs.opencv.org/modules/video/doc/motion_analysis_and_object_tracking.html
Here is an example
import cv2
backsub = cv2.BackgroundSubtractorMOG()
capture = cv2.VideoCapture("Balcony4_Vis.mpg")
if capture:
while True:
ret, frame = capture.read()
if ret:
fgmask = backsub.apply(frame, None, 0.01)
contours, hierarchy = cv2.findContours(fgmask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_NONE)
try: hierarchy = hierarchy[0]
except: hierarchy = []
for contour, hier in zip(contours, hierarchy):
(x,y,w,h) = cv2.boundingRect(contour)
if w > 10 and h > 10:
# figure out id
best_id = 1
.....
cv2.rectangle(frame, (x,y), (x+w,y+h), (255, 0, 0), 2)
cv2.putText(frame, str(best_id), (x,y-5), cv2.FONT_HERSHEY_SIMPLEX,
0.5, (255, 0, 0), 2)
cv2.imshow("Track", frame)
key = cv2.waitKey(10)
if key == ord('q'):
break