Opencv Watermark Transparency and Brightness - python

I have a logo and I am trying to put this logo into my video. When I add the logo with below codes, logo couldnt be original color, it shows transparent. But I dont want to transparency I need to put original color format.
I get this output:
This is my code:
img_path = 'ap_logo.png'
logo = cv2.imread(img_path,cv2.IMREAD_UNCHANGED)
#
#
watermark = image_resize(logo, height=300)
watermark = cv2.cvtColor(watermark, cv2.COLOR_BGR2BGRA)
watermark_h, watermark_w, watermark_c = watermark.shape
ret, frame = cap.read()
frame = cv2.flip(frame, 1)
frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
frame_h, frame_w, frame_c = frame.shape
# # overlay with 4 channel BGR and Alpha
overlay = np.zeros((frame_h, frame_w, 4), dtype='uint8')
for i in range(0, watermark_h):
print(i)
for j in range(0, watermark_w):
if watermark[i, j][3] != 0:
h_offset = frame_h - watermark_h
w_offset = frame_w - watermark_w
overlay[h_offset + i, w_offset + j] = watermark[i, j]
while(True):
ret, frame = cap.read()
frame = cv2.flip(frame, 1)
frame = cv2.rotate(frame, cv2.ROTATE_90_CLOCKWISE)
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2BGRA)
cv2.addWeighted(overlay, 0.25, frame, 1.0, 0, frame)
# Display the resulting frame
frame = cv2.cvtColor(frame, cv2.COLOR_BGRA2BGR)
if ret:
cv2.imshow('Frame', frame)
out.write(frame) # file a ilgili frame yazılıyor
if cv2.waitKey(1) & 0xFF == ord('q'):
break
#When everything done, relase the capture
cap.release()
out.release() # saved
cv2.destroyAllWindows()

Related

Save the edge detected frames from a video as a video (opencv)

I Want to save the edge detected frames as a video. I am able to preview the frames of the video but the output video doesn't play.
cap = cv2.VideoCapture("video.mp4")
fourcc = cv2.VideoWriter_fourcc(*'MP4V')
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280,720))
while(cap.isOpened()):
ret, frame = cap.read()
edges = cv.Canny(frame,50,50)
out.write(edges)
cv2.imshow('frame', edges)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
break
cap.release()
out.release()
There are three issues I would like to address.
You are applying Canny to each video frame. What is the output size:
print(edges.shape)
(720, 1280)
The dimension 720, 1280 means the frame is a gray-scale value. If the frame is a color image then the dimension will be (720, 1080, 3) for each channel R, G, B.
Therefore you need to initialize your VideoWriter object as a grey-scale images.
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280,720), isColor=False)
Make sure you are capturing the next frame:
ret, frame = cap.read()
if ret:
edges = cv.Canny(frame,50,50)
.
.
Make sure your frame are the same dimension with the VideoWriter object
while cap.isOpened():
ret, frame = cap.read()
if ret:
edges = cv2.Canny(frame, 50, 50)
edges = cv2.resize(edges, (1280, 720))
out.write(edges)
.
.
Code:
import cv2
cap = cv2.VideoCapture("video.mp4")
fourcc = cv2.VideoWriter_fourcc(*"mp4v")
out = cv2.VideoWriter('output.mp4', fourcc, 23.976, (1280, 720), isColor=False)
while cap.isOpened():
ret, frame = cap.read()
if ret:
edges = cv2.Canny(frame, 50, 50)
edges = cv2.resize(edges, (1280, 720))
out.write(edges)
cv2.imshow('frame', edges)
c = cv2.waitKey(1)
if c & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()

How to get last processed frame from video using opencv?

I want to extract last frame of video that have been processed before with Motion History Image (MHI) and I want to save last image processed by MHI.
Here is my code:
import numpy as np
import cv2
MHI_DURATION = 35
DEFAULT_THRESHOLD = 30
def main():
live_video = False
video_src = 1
if not live_video:
video_src = "data/vid1.mp4"
cv2.namedWindow('motion-history')
cv2.namedWindow('raw')
cv2.moveWindow('raw', 200, 0)
cam = cv2.VideoCapture(video_src)
ret, frame = cam.read()
h, w = frame.shape[:2]
prev_frame = frame.copy()
motion_history = np.zeros((h, w), np.float32)
timestamp = 0
while True:
ret, frame = cam.read()
if not ret:
break
frame_diff = cv2.absdiff(frame, prev_frame)
gray_diff = cv2.cvtColor(frame_diff, cv2.COLOR_BGR2GRAY)
ret, fgmask = cv2.threshold(gray_diff, DEFAULT_THRESHOLD, 1, cv2.THRESH_BINARY)
timestamp += 1
# update motion history
cv2.motempl.updateMotionHistory(fgmask, motion_history, timestamp, MHI_DURATION)
# normalize motion history
mh = np.uint8(np.clip((motion_history - (timestamp - MHI_DURATION)) / MHI_DURATION, 0, 1) * 255)
cv2.imshow('motion-history', mh)
# cv2.imshow('raw', frame)
prev_frame = frame.copy()
if 0xFF & cv2.waitKey(5) == 27:
break
cv2.destroyAllWindows()
And, can we process faster without loop through all frame in the video?

How to solve Opencv VideoWriter issues with global variables

I'mm writing this piece of python to display a stream of video from my webcam while at the same time record the video - which I've got working, however I've grayscaled the video streaming to my screen and time stamped it - but my recorded video is in colour! I've included the code below - I've tried using some global variables but nothing worked - any help, greatly appreciated
import cv2
import numpy as np
import time, datetime
import os
genericfilename = "recording"
filetime = str(time.time())
extension = '.avi'
filename = genericfilename + filetime +extension
frames_per_second = 100
res = '720p'
print("NEW FILE NAME: " + filename)
# Set resolution for the video capture
def change_res(cap, width, height):
cap.set(3, width)
cap.set(4, height)
# Standard Video Dimensions Sizes
STD_DIMENSIONS = {
"480p": (640, 480),
"720p": (1280, 720),
"1080p": (1920, 1080),
"4k": (3840, 2160),
}
# grab resolution dimensions and set video capture to it.
def get_dims(cap, res='1080p'):
width, height = STD_DIMENSIONS["480p"]
if res in STD_DIMENSIONS:
width,height = STD_DIMENSIONS[res]
## change the current caputre device
## to the resulting resolution
change_res(cap, width, height)
return width, height
# Video Encoding, might require additional installs
VIDEO_TYPE = {
'avi': cv2.VideoWriter_fourcc(*'XVID'),
#'mp4': cv2.VideoWriter_fourcc(*'H264'),
'mp4': cv2.VideoWriter_fourcc(*'XVID'),
}
def get_video_type(filename):
filename, ext = os.path.splitext(filename)
if ext in VIDEO_TYPE:
return VIDEO_TYPE[ext]
return VIDEO_TYPE['avi']
capture = cv2.VideoCapture(0)
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
get_dims(capture, res))
while(True):
ret, frame = capture.read()
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
font = cv2.FONT_ITALIC = 1
cv2.putText(grayFrame, str(datetime.datetime.now()), (-330, 460), font, 3,
(200, 200, 200), 2, cv2.LINE_AA)
cv2.imshow('combilift output', grayFrame)
# Press Q on keyboard to exit
if cv2.waitKey(1) & 0xFF == ord('q'):
break
if cv2.waitKey(1) & 0xFF == ord('r'):
print(datetime.datetime.now())
capture.release()
out.release()
cv2.destroyAllWindows()
You save the frame to video, then convert frame to gray.
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
If you want your recorded video to be gray, maybe reverse the order of operations and save grayFrame?
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(grayFrame)
If you want to also save the texts, put the text before writing frame to output.
Lets take a look at ur code
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
.....
while(True):
ret, frame = capture.read()
out.write(frame)
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
You first save out then convert color
The correct sequence should be
out = cv2.VideoWriter(filename, get_video_type(filename), 60,
.....
while(True):
ret, frame = capture.read()
grayFrame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
out.write(grayFrame)
I don't have data to test. Just in case you experience some issue with channels. You can use opencv merge(grayFrame,grayFrame,grayFrame) to create a normal 3 channel grey scale image and save to video

how to solve an error when converting RGB to Gray? (error: (-215) scn == 3 || scn == 4 in function cv::cvtColor)

I have a code that gets a video from a folder and does some calculations using contours and background subtraction. After that I am going to save that edited video into the folder. The code is shown below:
import numpy as np
import cv2
import time
# Capture video from file
cap = cv2.VideoCapture('test_video.mp4')
time.sleep(1)
fgbg = cv2.createBackgroundSubtractorMOG2()
j = 0
fourcc = cv2.VideoWriter_fourcc(*'MPEG')
out = cv2.VideoWriter('output.avi',fourcc, 20.0, (640,480))
while (cap.isOpened()):
ret, frame = cap.read()
if ret == True:
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
fgmask = fgbg.apply(gray)
_, contours, _ = cv2.findContours(fgmask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if contours:
areas = []
for contour in contours:
ar = cv2.contourArea(contour)
areas.append(ar)
max_area = max(areas or [0])
max_area_index = areas.index(max_area)
cnt = contours[max_area_index]
M = cv2.moments(cnt)
x, y, w, h = cv2.boundingRect(cnt)
cv2.drawContours(fgmask, [cnt], 0, (255,255,255), 3, maxLevel = 0)
if h < w:
j += 1
if j>10:
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,0,255),2)
if h > w:
j = 0
cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)
cv2.imshow('video',frame)
out.write(frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
else:
break
cap.release()
out.release()
cv2.destroyAllWindows()
This opens up a window and plays a video, then output.avi is created, but it doesn't contain any content.
cmd produces nothing. I just can't able to save a file in a proper way.
Please recommend a solution to this issue
The error is telling you that frame does not have 3 or 4 channels.
Can you check that your camera is initialized properly
if not cap.isOpened():
print("Camera not initialized")
return
It is returning you a valid frame
if not ret:
print("Problem reading frame")
return
else:
# Convert your frame to gray and find contours etc.

(cv2,capture) object is not callable

Basically, this code will detect object's motion in the scene. When the motion is detected, a red rectangle frame will track the object's motion. But, I added a new function into the code which is frame differencing. In general it is thresholding. When i run the code it says:"cv2.capture" object is not callable.
import cv2.cv as cv
class Target:
def __init__(self):
self.capture = cv.CaptureFromCAM(0)
cv.NamedWindow("Target", 1)
def run(self):
# Capture first frame to get size
ret, current_frame = self.capture()
previous_frame = current_frame
frame = cv.QueryFrame(self.capture)
frame_size = cv.GetSize(frame)
color_image = cv.CreateImage(cv.GetSize(frame), 8, 3)
grey_image = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_8U, 1)
moving_average = cv.CreateImage(cv.GetSize(frame), cv.IPL_DEPTH_32F, 3)
first = True
while True:
current_frame_gray = cv2.cvtColor(current_frame,cv2.COLOR_BGR2GRAY)
previous_frame_gray = cv2.cvtColor(previous_frame, cv2.COLOR_BGR2GRAY)
frame_diff = cv2.absdiff(current_frame_gray,previous_frame_gray)
closest_to_left = cv.GetSize(frame)[0]
closest_to_right = cv.GetSize(frame)[1]
color_image = cv.QueryFrame(self.capture)
# Smooth to get rid of false positives
cv.Smooth(color_image, color_image, cv.CV_GAUSSIAN, 3, 0)
if first:
difference = cv.CloneImage(color_image)
temp = cv.CloneImage(color_image)
cv.ConvertScale(color_image, moving_average, 1.0, 0.0)
first = False
else:
cv.RunningAvg(color_image, moving_average, 0.020, None)
# Convert the scale of the moving average.
cv.ConvertScale(moving_average, temp, 1.0, 0.0)
# Minus the current frame from the moving average.
cv.AbsDiff(color_image, temp, difference)
# Convert the image to grayscale.
cv.CvtColor(difference, grey_image, cv.CV_RGB2GRAY)
# Convert the image to black and white.
cv.Threshold(grey_image, grey_image, 70, 255, cv.CV_THRESH_BINARY)
# Dilate and erode to get people blobs
cv.Dilate(grey_image, grey_image, None, 18)
cv.Erode(grey_image, grey_image, None, 10)
storage = cv.CreateMemStorage(0)
contour = cv.FindContours(grey_image, storage, cv.CV_RETR_CCOMP, cv.CV_CHAIN_APPROX_SIMPLE)
points = []
while contour:
bound_rect = cv.BoundingRect(list(contour))
contour = contour.h_next()
pt1 = (bound_rect[0], bound_rect[1])
pt2 = (bound_rect[0] + bound_rect[2], bound_rect[1] + bound_rect[3])
points.append(pt1)
points.append(pt2)
cv.Rectangle(color_image, pt1, pt2, cv.CV_RGB(255,0,0), 1)
cv.ShowImage("Target", color_image)
cv.ShowImage("frame_diff", frame_diff)
# Listen for ESC key
c = cv.WaitKey(7) % 0x100
if c == 27:
break
if __name__=="__main__":
t = Target()
t.run()
This is the original frame differencing code that I wanted transfer from:
import cv2
cap = cv2.VideoCapture(0)
ret, current_frame = cap.read()
previous_frame = current_frame
while(cap.isOpened()):
current_frame_gray = cv2.cvtColor(current_frame, cv2.COLOR_BGR2GRAY)
previous_frame_gray = cv2.cvtColor(previous_frame, cv2.COLOR_BGR2GRAY)
frame_diff = cv2.absdiff(current_frame_gray,previous_frame_gray)
cv2.imshow('frame diff ',frame_diff)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
previous_frame = current_frame.copy()
ret, current_frame = cap.read()
cap.release()
cv2.destroyAllWindows()
You can't call the capture object, but you can read from it by calling its read method. Changing your frame return code to:
ret, current_frame = self.capture.read()
Should fix this.
Edit:
The two lines:
ret, current_frame = self.capture.read()
previous_frame = current_frame
Will work for VideoCapture but not CaptureFromCAM. You apparently don't need them since you can take a frame by doing:
frame = cv.QueryFrame(self.capture)

Categories