when I write this code: (my entire code, school project on Augmented Reality)
Everything worked perfectly until I tried to run the video.
...........................................................................................................................................................................................................
import cv2
import numpy as np
cap=cv2.VideoCapture(2)
imgTarget=cv2.imread('F1racecars.jpeg')
vidTarget= cv2.VideoCapture('F1racecars.mp4')
success, vidTarget = vidTarget.read()
imgTarget=cv2.resize(imgTarget,(640,360))
hT, wT, cT = imgTarget.shape
vidTarget=cv2.resize(vidTarget,(wT,hT))
orb = cv2.ORB_create(nfeatures=1000)
kp1, des1 = orb.detectAndCompute(imgTarget,None)
detect = False
fcount = 0
while True:
success, imgWebcam= cap.read()
imgAug = imgWebcam.copy()
imgWarp = np.zeros((imgWebcam.shape[1], imgWebcam.shape[0],imgWebcam.shape[2]))
masknew = np.zeros((imgWebcam.shape[0], imgWebcam.shape[1],imgWebcam.shape[2]), np.uint8)
maskInv = np.zeros((imgWebcam.shape[0], imgWebcam.shape[1], imgWebcam.shape[2]), np.uint8)
Mergecamfeed = np.zeros((imgWebcam.shape[0], imgWebcam.shape[1], imgWebcam.shape[2]), np.uint8)
ARfinal = np.zeros((imgWebcam.shape[0], imgWebcam.shape[1], imgWebcam.shape[2]), np.uint8)
if detect is False:
vidTarget.set(cv2.CAP_PROP_POS_FRAMES,0)
fcount =0
else:
if fcount == vidTarget.get(cv2.CAP_PROP_FRAME_COUNT, 0):
vidTarget.set(cv2.CAP_PROP_POS_FRAMES, 0)
fcount = 0
success, vidTarget= vidTarget.read()
vidTarget= cv2.resize(vidTarget, (wT, hT))
kp2, des2 = orb.detectAndCompute(imgWebcam,None)
if des2 is None: print(False)
else:
bf = cv2.BFMatcher()
featmatch = bf.knnMatch(des1,des2,k=2)
good=[]
for m,n in featmatch:
if m.distance < 0.75 * n.distance: good.append(m)
print(len(good))
if len(good)>20:
detect = True
srcpts = np.float32([kp1[m.queryIdx].pt for m in good]).reshape(-1, 1, 2)
dstpts = np.float32([kp2[m.trainIdx].pt for m in good]).reshape(-1, 1, 2)
matrix, mask = cv2.findHomography(srcpts,dstpts, cv2.RANSAC, 5)
print(matrix)
pts = np.float32([[0,0],[0,360],[640,360],[640,0]]).reshape(-1, 1, 2)
dst = cv2.perspectiveTransform(pts,matrix)
cv2.polylines(imgWebcam,[np.int32(dst)],True,(255,0,255),3)
imgWarp = cv2.warpPerspective(vidTarget,matrix, (imgWebcam.shape[1],imgWebcam.shape[0]))
cv2.fillPoly(masknew, [np.int32(dst)], (255,255,255))
maskInv = cv2.bitwise_not(masknew)
Mergecamfeed = cv2.bitwise_and(imgAug,imgAug,None, mask = maskInv[:,:,0])
ARfinal = cv2.bitwise_or(imgWarp, Mergecamfeed)
cv2.imshow('imgTarget', imgTarget)
cv2.imshow('imgTargetVdo', vidTarget)
cv2.imshow('webcam', imgWebcam)
cv2.imshow('warp', imgWarp)
cv2.imshow('mask', masknew)
cv2.imshow('Modified mask', maskInv)
cv2.imshow('Aug Image', Mergecamfeed)
cv2.imshow('Augmented Reality Final O/P', ARfinal)
cv2.waitKey(1)
fcount += 1
It shows like this:
AttributeError: 'numpy.ndarray' object has no attribute 'set'
Normally we ask for the full error message, with traceback. That makes it easier to identify where the error occurs. In this case though, set is only used a couple of times.
vidTarget.set(cv2.CAP_PROP_POS_FRAMES,0)
What's this thing vidTarget? The error says it's a numpy array, and is clear that such an object does not have a set method. Experienced numpy users also know that. So what kind of object did you expect it to be?
We see attribute errors for one of two reasons. Either the code writer did not read the documentation, and tried to use a non-existent method. Or the variable in question is not what he expected. You should know, at every, step what the variable is - not just guess or hope, know. Test if necessary.
edit
Initially
vidTarget= cv2.VideoCapture('F1racecars.mp4')
From a quick read of cv2 docs, this has get/set methods
but then you do
succses, vidTarget = vidTarget.read()
# and resize
That redefines vidTarget.
Related
I have a goal to do homography on a live video by capturing my screen and processing it.
In order to do so, I took the code from this link, and manipulated it inside a while loop as follows:
from __future__ import print_function
import cv2 as cv
import numpy as np
from windowcapture import WindowCapture
# initialize the WindowCapture class
capture = WindowCapture('My Window')
bar_img = cv.imread('hammer.jpg',cv.IMREAD_GRAYSCALE)
while(True):
# get an updated image of the game
screenshot = capture.get_screenshot()
screenshot = cv.cvtColor(screenshot,cv.IMREAD_GRAYSCALE)
if bar_img is None or screenshot is None:
print('Could not open or find the images!')
exit(0)
#-- Step 1: Detect the keypoints using SURF Detector, compute the descriptors
minHessian = 400
detector = cv.SIFT_create()
keypoints_obj, descriptors_obj = detector.detectAndCompute(bar_img, None)
keypoints_scene, descriptors_scene = detector.detectAndCompute(screenshot, None)
#-- Step 2: Matching descriptor vectors with a FLANN based matcher
# Since SURF is a floating-point descriptor NORM_L2 is used
matcher = cv.DescriptorMatcher_create(cv.DescriptorMatcher_FLANNBASED)
knn_matches = matcher.knnMatch(descriptors_obj, descriptors_scene, 2)
#-- Filter matches using the Lowe's ratio test
ratio_thresh = 0.75
good_matches = []
for m,n in knn_matches:
if m.distance < ratio_thresh * n.distance:
good_matches.append(m)
#-- Draw matches
img_matches = np.empty((max(bar_img.shape[0], screenshot.shape[0]), bar_img.shape[1]+screenshot.shape[1], 3), dtype=np.uint8)
cv.drawMatches(bar_img, keypoints_obj, screenshot, keypoints_scene, good_matches, img_matches, flags=cv.DrawMatchesFlags_NOT_DRAW_SINGLE_POINTS)
#-- Localize the object
obj = np.empty((len(good_matches),2), dtype=np.float32)
scene = np.empty((len(good_matches),2), dtype=np.float32)
for i in range(len(good_matches)):
#-- Get the keypoints from the good matches
obj[i,0] = keypoints_obj[good_matches[i].queryIdx].pt[0]
obj[i,1] = keypoints_obj[good_matches[i].queryIdx].pt[1]
scene[i,0] = keypoints_scene[good_matches[i].trainIdx].pt[0]
scene[i,1] = keypoints_scene[good_matches[i].trainIdx].pt[1]
H, _ = cv.findHomography(obj, scene, cv.RANSAC)
#-- Get the corners from the image_1 ( the object to be "detected" )
obj_corners = np.empty((4,1,2), dtype=np.float32)
obj_corners[0,0,0] = 0
obj_corners[0,0,1] = 0
obj_corners[1,0,0] = bar_img.shape[1]
obj_corners[1,0,1] = 0
obj_corners[2,0,0] = bar_img.shape[1]
obj_corners[2,0,1] = bar_img.shape[0]
obj_corners[3,0,0] = 0
obj_corners[3,0,1] = bar_img.shape[0]
scene_corners = cv.perspectiveTransform(obj_corners, H)
#-- Draw lines between the corners (the mapped object in the scene - image_2 )
cv.line(img_matches, (int(scene_corners[0,0,0] + bar_img.shape[1]), int(scene_corners[0,0,1])),\
(int(scene_corners[1,0,0] + bar_img.shape[1]), int(scene_corners[1,0,1])), (0,255,0), 4)
cv.line(img_matches, (int(scene_corners[1,0,0] + bar_img.shape[1]), int(scene_corners[1,0,1])),\
(int(scene_corners[2,0,0] + bar_img.shape[1]), int(scene_corners[2,0,1])), (0,255,0), 4)
cv.line(img_matches, (int(scene_corners[2,0,0] + bar_img.shape[1]), int(scene_corners[2,0,1])),\
(int(scene_corners[3,0,0] + bar_img.shape[1]), int(scene_corners[3,0,1])), (0,255,0), 4)
cv.line(img_matches, (int(scene_corners[3,0,0] + bar_img.shape[1]), int(scene_corners[3,0,1])),\
(int(scene_corners[0,0,0] + bar_img.shape[1]), int(scene_corners[0,0,1])), (0,255,0), 4)
#-- Show detected matches
cv.imshow('Good Matches & Object detection', img_matches)
cv.waitKey()
if cv.waitKey(1) == ord('q'):
cv.destroyAllWindows()
break
print('Done.')
The class WindowCapture that I used uses win32gui to capture the window (maybe it makes a difference if I used it like this and not imread?)
I get the following error when I run the code:
C:\Users\Tester\AppData\Local\Temp\pip-req-build-1i5nllza\opencv\modules\calib3d\src\fundam.cpp:385: error: (-28:Unknown error code -28) The input arrays should have at least 4 corresponding point sets to calculate Homography in function 'cv::findHomography'
Any idea why it happens?
The code is for the implementation of a SIFT-based algorithm with FLANN matcher on a captured image from the webcam. The error for some reason is in the knnMatch where we deal with the captured image. The attached image link shows the error causing line. It would be great if someone could provide some solution to this issue, please comment below for specific details.
import cv2
import numpy as np
MIN_MATCH_COUNT = 30
detector = cv2.xfeatures2d.SIFT_create()
FLANN_INDEX_KDITREE = 0
flannParam = dict(algorithm=FLANN_INDEX_KDITREE,tree=5)
searchParam = dict(check = 50)
flann=cv2.FlannBasedMatcher(flannParam,searchParam)
trainImg=cv2.imread("E:\\EXCHANGE_Courses\\training_img1.jpg")
trainImg1 = cv2.cvtColor(trainImg,cv2.COLOR_BGR2GRAY)
trainKP,trainDecs = detector.detectAndCompute(trainImg1,None)
cam = cv2.VideoCapture(1)
print(cam.isOpened())
for i in range(1):
return_value, image = cam.read()
cv2.imwrite('capture'+str(i)+'.jpg', image)
del(cam)
while True:
QImage = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
queryKP,queryDesc = detector.detectAndCompute(QImage,None)
# Now match the key descriptions from the training image and the query image
# np.asarray(des1,np.float32),np.asarray(des2,np.float32),k=2
# queryDesc,trainDecs, k=2
matches=flann.knnMatches(queryDesc,trainDecs, k=2)
print("upper part clear")
# Filter the pool of keypoints as we need to collect the key points of interest only with the object in mind
goodMatch=[]
for m,n in matches:
if(m.distance<0.75*n.distance):
goodMatch.append(m)
print("all ok here")
if(len(goodMatch)>MIN_MATCH_COUNT):
tp=[]
qp=[]
for m in goodMatch:
tp.append(trainKP[m.trainIdx].pt)
qp.append(queryKP[m.queryIdx].pt)
tp,qp = np.float32((tp,qp))
H,status = cv2.findHomography(tp,qp,cv2.RANSAC,3.0)
h,w=trainImg.shape
trainBorder = np.float32([[[0,0],[0,h-1],[w-1,h-1],[0,w-1]]])
queryBorder = cv2.perspectiveTransform(trainBorder,H)
# changed QImageBGR to image
cv2.polylines(QImage,[np.uint8(queryBorder)],True,(0,255,0),3)
else:
print("Not enough matches - %d/%d" %len(goodMatch),MIN_MATCH_COUNT)
cv2.imshow('results',QImage)
#print ("Not enough matches are found - %d/%d" % (len(goodMatch),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(trainImg1,trainKP,QImage,queryKP,goodMatch,None,**draw_params)
#plt.imshow(img3, 'gray'),plt.show()
if cv2.waitKey(10)==ord('q'):
break
#cam.release()
#cv2.destroyAllWindows()
A bit late to the party, but I'm guessing you meant knnMatch rather than knnMatches.
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('/home/manoj/Pictures/Untitled-1.jpg')
out = np.zeros(im.shape,np.uint8)
gray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
thresh = cv2.adaptiveThreshold(gray,255,1,1,11,2)
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)
I used this python code with Opencv for character recognition but I get this error while running the code.
AttributeError: 'module' object has no attribute 'KNearest'
Since the new OpenCV's version you need to replace
model = cv2.KNearest()
by:
model = cv2.ml.KNearest_create()
Moreover, the line:
model.train(samples,responses)
is also going to raise an error, this should fix it:
model.train(samples,cv2.ml.ROW_SAMPLE,responses) # Might be adapted
Hope this will help.
The issue I'm having is that the two scripts below are both outputting this error: https://i.imgur.com/sLH6Mv4.png
TypeError: FeatureDetector.detect() takes at most 2 arguments (3 given)
which I can avoid in the script 2 below by deleting:
useProvidedKeypoints = False
from the end of
kp, descritors = surf.detect(imgg,None,useProvidedKeypoints = False)
which leads to this error in the 2nd script :https://i.imgur.com/ap0odal.png
TypeError: float() argument must be a string or a number
And this error in the first script: i.imgur.com/UVzNvP1.png (2 link limit add manually)
TypeError: trainData data type = 17 is not supported
Any help would be greatly appreciated and the main thing I want to come out of this is with a script I can tweak and edit till I understand the functions involved slightly better.
Summary; I'm not really sure why kp, descritors = surf.detect(imgg,None,useProvidedKeypoints = False) is telling me there too many arguments because the person who helped me write this seemed to think this should work.
1
import cv2
import numpy as np
img =cv2.imread('win18.jpg')
imgg =cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
surf = cv2.SURF()
kp, descritors = surf.detect(imgg,None,useProvidedKeypoints = False)
samples = np.array(descritors)
responses = np.arange(len(kp),dtype = np.float32)
knn = cv2.KNearest()
knn.train(samples,responses)
template = cv2.imread('win17.jpg')
templateg= cv2.cvtColor(template,cv2.COLOR_BGR2GRAY)
keys,desc = surf.detect(templateg,None,useProvidedKeypoints = False)
for h,des in enumerate(desc):
des = np.array(des,np.float32).reshape((1,128))
retval, results, neigh_resp, dists = knn.find_nearest(des,1)
res,dist = int(results[0][0]),dists[0][0]
if dist<0.1:
color = (0,0,255)
else:
print dist
color = (255,0,0)
x,y = kp[res].pt
center = (int(x),int(y))
cv2.circle(img,center,2,color,-1)
x,y = keys[h].pt
center = (int(x),int(y))
cv2.circle(template,center,2,color,-1)
cv2.imshow('img',img)
cv2.imshow('tm',template)
cv2.waitKey(0)
cv2.destroyAllWindows()
2
import cv2
import numpy
opencv_haystack =cv2.imread('win12.jpg')
opencv_needle =cv2.imread('win1.jpg')
ngrey = cv2.cvtColor(opencv_needle, cv2.COLOR_BGR2GRAY)
hgrey = cv2.cvtColor(opencv_haystack, cv2.COLOR_BGR2GRAY)
hessian_threshold = 85
detector = cv2.SURF(hessian_threshold)
(hkeypoints, hdescriptors) = detector.detect(hgrey, None, useProvidedKeypoints = False)
(nkeypoints, ndescriptors) = detector.detect(ngrey, None, useProvidedKeypoints = False)
rowsize = len(hdescriptors) / len(hkeypoints)
if rowsize > 1:
hrows = numpy.array(hdescriptors, dtype = numpy.float32).reshape((-1, rowsize))
nrows = numpy.array(ndescriptors, dtype = numpy.float32).reshape((-1, rowsize))
else:
hrows = numpy.array(hdescriptors, dtype = numpy.float32)
nrows = numpy.array(ndescriptors, dtype = numpy.float32)
rowsize = len(hrows[0])
samples = hrows
responses = numpy.arange(len(hkeypoints), dtype = numpy.float32)
knn = cv2.KNearest()
knn.train(samples,responses)
if dist < 0.1:
color = (0, 0, 255)
else:
color = (255, 0, 0)
x,y = hkeypoints[res].pt
center = (int(x),int(y))
cv2.circle(opencv_haystack,center,2,color,-1)
x,y = nkeypoints[i].pt
center = (int(x),int(y))
cv2.circle(opencv_needle,center,2,color,-1)
cv2.imshow('haystack',opencv_haystack)
cv2.imshow('needle',opencv_needle)
cv2.waitKey(0)
cv2.destroyAllWindows()
Hi I know it's late but for the ones still facing the problem, try replacing detect() with detectAndCompute().
I got the error removed this way.
when in doubt, ...
>>> s = cv2.SURF()
>>> help(s.detect)
Help on built-in function detect:
detect(...)
detect(image[, mask]) -> keypoints
so, your assumptions about the args to SURF.detect() were quite off.
I am trying to extract a background image from a video so I can detect moving objects in it.
I have found functions like cv2.BackgroundSubtractorMOG(), however I just can't get it to work.
Does someone have some experience using this ?
I have created object mog = cv2.BackgroundSubtractorMOG(300,-1,-1,-1)
Then I try mog.apply(Nmat,Nforemat,-1), but that doesnt seem to work, I get the following
error:
......\OpenCV-2.4.0\modules\video\src\bgfg_gaussmix.cpp:117: error: (-215) CV_MAT_DEPTH(frameType) == CV_8U
Nmat and N foremat are numpy arrays because i was also getting an error if they weren't.
Here is work in progress...
import cv
import cv2
import numpy as np
if __name__ == '__main__':
cv.NamedWindow("test1", cv.CV_WINDOW_AUTOSIZE)
cv.NamedWindow("test2", cv.CV_WINDOW_AUTOSIZE)
capture = cv.CreateFileCapture('test.avi')
frame = cv.QueryFrame(capture)
img = cv.CreateImage(cv.GetSize(frame),8,1)
thresh = cv.CreateImage(cv.GetSize(frame),8,1)
foreground = cv.CreateImage(cv.GetSize(frame),8,1)
foremat = cv.GetMat(foreground)
Nforemat = np.array(foremat, dtype=np.float32)
thresh = cv.CreateImage(cv.GetSize(img),8,1)
mog = cv2.BackgroundSubtractorMOG()
loop = True
nframes=0
while(loop):
frame = cv.QueryFrame(capture)
mat = cv.GetMat(frame)
Nmat = np.array(mat, dtype=np.float32)
cv.CvtColor(frame,img,cv.CV_BGR2GRAY)
if (frame == None):
break
mog.apply(Nmat,Nforemat,-1)
cv.Threshold(img,thresh,100,255,cv.CV_THRESH_BINARY)
cv.ShowImage("test1", thresh)
cv.ShowImage("test2",frame)
char = cv.WaitKey(50)
if (char != -1):
if (char == 27):
break
cv.DestroyWindow("test1")
cv.DestroyWindow("test2")
change
Nmat = np.array(mat, dtype=np.float32)
for
Nmat = np.array(mat, dtype=np.uint8)
Why are you using these lines:
thresh = cv.CreateImage(cv.GetSize(img),8,1)
and
cv.Threshold(img,thresh,100,255,cv.CV_THRESH_BINARY)
?