OpenCV edge enhancement - c++

I am performing background subtraction to obtain a moving car from a video as below ( Running average background modeling)
I am applying findContours() after this to draw a polygon around the car.
As you can see, the quality of the obtained output is not great. Is there any way I can enhance the edges of the car to make it more prominent and cut out the extraneous noise surrounding it. I tried performing morphological closing(dilate -> erode) to fill the gaps, but the output was not as expected.

This might be overkill and far from a quick solution but Level Set Methods would be very suited to extract the presegmented car.

You can try to apply background subtraction by using cv2.createBackgroundSubtractorMOG2().
Code:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
out = cv2.createBackgroundSubtractorMOG2()
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
output = cv2.VideoWriter('output.avi', fourcc, 20.0, (640,480), isColor=False)
while(cap.isOpened()):
ret, frame = cap.read()
if ret==True:
frame = cv2.flip(frame,180)
outmask = out.apply(frame)
output.write(outmask)
cv2.imshow('original', frame)
cv2.imshow('Motion Tracker', outmask)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
output.release()
cap.release()
cv2.destroyAllWindows()

Related

How can i use Viola Jones Algorithm to detect the Face as a region of interest and crop it till the rectangle box?

I want to detect the face in the video frame and remove the other elements such as background etc. and just want to focus on the facial region, for this i need to use viola jones algorithm, czn anyone give me a hint or suitable answer for this.
import cv2
import sys
imagep='6.jpg'#sys.argv[1]
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')
i=cv2.imread(imagep)
gray=cv2.imread(imagep,cv2.COLOR_BGR2GRAY)
f=face_cascade.detectMultiScale(gray,scaleFactor=1.1,minNeighbors=5,minSize=(30,30),flags=cv2.CASCADE_SCALE_IMAGE)
print("Found {0} faces!".format(len(f)))
for(x,y,w,h) in f:
cv2.rectangle(i,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow("Faces found",i)
cv2.waitKey(0)
Once you have the upper left and and bottom right coordinates of the rectangle in which the face is contained, You can just crop the original image on the basis of those coordinates. Let's suppose initial image is stored in the frame variable, follow the code
face = face_recognition.detectMultiScale(frame, scaleFactor = 1.8, minNeighbors = 5) #detects coordinates of face
resultant_image = frame[face[0][1] : (face[0][1] + face[0][3]),face[0][0] : (face[0][0] + face[0][2]), :] # gives you cropped image

segmentation of overlapping cells

The following python script should split overlapping cells apart which does work quite good. The problem is now that it also splits some of the cells apart which don't overlap with other cells. To make things clear to you i'll add my input image and the output image.
The input:input image
The output:
output image
Output image where I marked two "bad" segmented cells:Output image with marked errors
Thresholded image: Thresholded image
Does someone have an idea how to avoid this problem or is the whole approach not good enough to process these kind of images?
I am using the following piece of code to segment the cells:
from skimage.feature import peak_local_max
from skimage.morphology import watershed
from scipy import ndimage
import numpy as np
import cv2
# load the image and perform pyramid mean shift filtering
# to aid the thresholding step
image = cv2.imread('C:/Users/Root/Desktop/image13.jpg')
shifted = cv2.pyrMeanShiftFiltering(image, 41, 51)
# convert the mean shift image to grayscale, then apply
# Otsu's thresholding
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255,
cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
im = gray.copy()
D = ndimage.distance_transform_edt(thresh)
localMax = peak_local_max(D, indices=False, min_distance=3,
labels=thresh)
# perform a connected component analysis on the local peaks,
# using 8-connectivity, then apply the Watershed algorithm
markers = ndimage.label(localMax, structure=np.ones((3, 3)))[0]
labels = watershed(-D, markers, mask=thresh)
print("[INFO] {} unique segments found".format(len(np.unique(labels)) - 1))
conts=[]
for label in np.unique(labels):
# if the label is zero, we are examining the 'background'
# so simply ignore it
if label == 0:
continue
# otherwise, allocate memory for the label region and draw
# it on the mask
mask = np.zeros(gray.shape, dtype="uint8")
mask[labels == label] = 255
# detect contours in the mask and grab the largest one
cnts = cv2.findContours(mask.copy(), cv2.RETR_EXTERNAL,
cv2.CHAIN_APPROX_SIMPLE)[-2]
c = max(cnts, key=cv2.contourArea)
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect)
box = np.int0(box)
if cv2.contourArea(c) > 150:
#cv2.drawContours(image,c,-1,(0,255,0))
cv2.drawContours(image,[box],-1,(0,255,0))
cv2.imshow("output", image)
cv2.waitKey()

Eye Pupil Tracking using Hough Circle Transform

I have a project of Eye Controlled Wheel Chair where I need to detect the pupil of the Eye and according to its motion the Wheel Chair moves. As a test for the code I am writing I performed the script on a static image. The image is exactly where the camera will be put. The camera will be an IR one.
Note: I am using compiled OpenCV 3.1.0-dev and Python2.7 on Windows Platfrom
The detected circle I wanted using Houghcircle transform:
After that I am working on a code to detect the same thing only by using an IR camera.
The results from the static image code is very reliable to me, but the problem is the code with the IR camera.
The code I have wrote so far is:
import cv2
import numpy as np
cap = cv2.VideoCapture(0)
while True:
## Read Image
ret, image = cap.read()
## Convert to 1 channel only grayscale image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## CLAHE Equalization
cl1 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
clahe = cl1.apply(gray)
## medianBlur the image to remove noise
blur = cv2.medianBlur(clahe, 7)
## Detect Circles
circles = cv2.HoughCircles(blur ,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=7,maxRadius=21)
if circles != None:
circles = np.round(circles[0,:]).astype("int")
for circle in circles[0,:]:
# draw the outer circle
cv2.circle(image,(circle[0],circle[1]),circle[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(image,(circle[0],circle[1]),2,(0,0,255),3)
if cv2.waitKey(1) in [27, ord('q'), 32]:
break
cap.release()
cv2.destroyAllWindows()
I always get this error:
**if circles != None:
FutureWarning: comparison to `None` will result in an elementwise object comparison in the future.
Traceback (most recent call last):
cv2.circle(image,(circle[0],circle[1]),circle[2],(0,255,0),2)
IndexError: invalid index to scalar variable.**
For any questions about the code for the static image, the code is:
import cv2
import numpy as np
## Read Image
image = cv2.imread('eye.tif')
imageBackup = image.copy()
## Convert to 1 channel only grayscale image
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
## CLAHE Equalization
cl1 = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
clahe = cl1.apply(gray)
## medianBlur the image to remove noise
blur = cv2.medianBlur(clahe, 7)
## Detect Circles
circles = cv2.HoughCircles(blur ,cv2.HOUGH_GRADIENT,1,20,
param1=50,param2=30,minRadius=7,maxRadius=21)
for circle in circles[0,:]:
# draw the outer circle
cv2.circle(image,(circle[0],circle[1]),circle[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(image,(circle[0],circle[1]),2,(0,0,255),3)
cv2.imshow('Final', image)
cv2.imshow('imageBackup', imageBackup)
cv2.waitKey(0)
cv2.destroyAllWindows()
So i tried it out my self and i had the same error. So i modified the code like i already proposed. Here is the snipped:
if circles != None:
for circle in circles[0,:]:
# draw the outer circle
cv2.circle(image,(circle[0],circle[1]),circle[2],(0,255,0),2)
# draw the center of the circle
cv2.circle(image,(circle[0],circle[1]),2,(0,0,255),3)
In addition you can try to use cv2.Canny for better results. Over and out :)

Why is my OpenCV Video Refusing to Write to Disk?

So I am starting to get very confused by the openCV libraries ability to write out video to disk, because even the openCV documentation is not terribly clear as to how the video actually gets written in this case. The code I have below seems to collect the data just fine but the video file it tries to write has no data in it. All I want to do is take a video that I know I can, change the data within it to a ramp between 0 and 255, and then write that data back out to disk. However, the final I/O step is not cooperating for reasons I don't understand. Can anyone help? Find the code below:
import numpy as np
import cv2
import cv2.cv as cv
cap = cv2.VideoCapture("/Users/Steve/Documents/TestVideo.avi") #The video
height = cap.get(cv.CV_CAP_PROP_FRAME_HEIGHT) #We get some properties of the video
width = cap.get(cv.CV_CAP_PROP_FRAME_WIDTH)
fps = cap.get(cv.CV_CAP_PROP_FPS)
fourcc = cv2.cv.CV_FOURCC(*'PDVC') #This is essential for testing
out = cv2.VideoWriter('output.avi',fourcc, int(fps), (int(width),int(height)))
xaxis = np.arange(width,dtype='int')
yaxis = np.arange(height,dtype='int')
xx,yy = np.meshgrid(xaxis,yaxis)
ramp=256*xx/int(width) #This is a horizontal ramp image that scales from 0-255 across the width of the image
i=0
while(cap.isOpened()):
if i%100==0: print i
i+=1
ret, frame = cap.read() #Grab a frame
if ret==True:
# Change the frame data to the ramp instead of the original video
frame[:,:,0]=ramp #The camera is B/W so the image is in B/W
frame[:,:,1]=ramp
frame[:,:,2]=ramp
out.write(frame) #Write to disk?
cv2.imshow('frame',frame) # I see the ramp as an imshow
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release() #Clear windows
out.release()
cv2.destroyAllWindows()
Your code is generally correct, but is likely silently failing at some step along the way.
try adding some debug lines:
out = cv2.VideoWriter('output2.avi',fourcc, int(fps), (int(width),int(height)))
or
else:
print "frame %d is false" % i
break
When I was testing your code locally I found the fps was set to 0 for most .avi files I read. Manually setting it to 15 or 30 worked.
I also didn't have any luck getting your fourcc to work on my machine (osx), but this one worked fine.
fourcc = cv2.cv.CV_FOURCC('m', 'p', '4', 'v')

OpenCV 2.4.9 for Python, cannot find chessboard (camera calibration tutorial)

I am trying to calibrate camera using OpenCV tools according to the following this guide.
The problem is that function findChessboardCorners cannot find any chessboard on images I tried. I used a lot of them - even just plain chessboard pattern. In any case, nothing was detected.
Here is the code (almost the same as from link above):
import numpy as np
import cv2
import glob
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((6*7,3), np.float32)
objp[:,:2] = np.mgrid[0:7,0:6].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
images = glob.glob('*.png')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (7,6),None)
# If found, add object points, image points (after refining them)
if ret == True:
objpoints.append(objp)
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
imgpoints.append(corners2)
# Draw and display the corners
img = cv2.drawChessboardCorners(img, (7,6), corners2,ret)
cv2.imshow('img',img)
cv2.waitKey(500)
cv2.destroyAllWindows()
The only change I made is that i switched from .jpg files to .png files - for some reason, function imread cannot read jpg images (that's another strange problem for other topic).
Thank you in advance for advices!
Image ref:
Just for other Python newbies that may go down this road. Working code:
import numpy as np
import cv2
import glob
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# Arrays to store object points and image points from all the images.
imgpoints = [] # 2d points in image plane.
images = glob.glob('*.png')
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret = False
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (7,7))
# If found, add object points, image points (after refining them)
if ret == True:
cv2.cornerSubPix(gray, corners, (11,11), (-1,-1), criteria)
imgpoints.append(corners)
# Draw and display the corners
cv2.drawChessboardCorners(img, (7,7), corners, ret)
cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Two main points:
You have to carefully count dimension of you pattern. (7,7) is for usual chessboard.
Line img = cv2.drawChessboardCorners(img, (7,6), corners2,ret) doesn't work, you have to change it to cv2.drawChessboardCorners(img, (7,6), corners2,ret) (function doesn't return image).
Thanks to AldurDisciple!