Skip to content

Instantly share code, notes, and snippets.

@jiristepan
Last active April 16, 2020 09:35
Show Gist options
  • Save jiristepan/58e6538fd01bf12621e7a58cbefe8103 to your computer and use it in GitHub Desktop.
Save jiristepan/58e6538fd01bf12621e7a58cbefe8103 to your computer and use it in GitHub Desktop.
import numpy as np
import cv2
import sys
# input and output folders
basedir = "/mnt/c/MEDIA"
infolder = "input"
outfolder = "output"
if (len(sys.argv) != 2):
print("Missing input file argument")
print("Usage: python3 ./search_red.py $filename")
print("Example: python3 ./search_red.py DVI196.MOV")
print("\nInput fille should be in %s/%s and the output folder %s/%s should be created" %(basedir,infolder, basedir, outfolder))
quit()
infile=sys.argv[1] # file name of file to process
inputFileFull= "%s/%s/%s" % (basedir,infolder,infile)
outputFileFull= "%s/%s/%s" % (basedir,outfolder,infile)
print("Searching red pixels in %s -> %s" %(inputFileFull, outputFileFull))
# open capturing device and check
cap = cv2.VideoCapture(inputFileFull)
if (cap.isOpened() == False):
print("Unable to read video file")
# get video stream params
frame_width = int(cap.get(3))
frame_height = int(cap.get(4))
# prepare output video file
# Define the codec and create VideoWriter object.
out = cv2.VideoWriter("/mnt/c/MEDIA/output/%s.avi" % (infile.replace(".","-")),cv2.VideoWriter_fourcc('M','J','P','G'), 10, (frame_width,frame_height))
# configurations - color boundaris
# warning - the color code is not RGB, but reverse BGR
boundaries = ([00, 00, 123], [88, 88 , 190]) # bottom and top of color space to filter
STARTTRESHOLD = 1 # how many red pixels trigger screenshot
waitUntilNextFileFrames = 5 #how many frames skip until next screenshot
treshold = STARTTRESHOLD #actual treshold
nextFileFrame=waitUntilNextFileFrames # actual next frame
frames = 0 # frame counter
files = 0 # genarated files counter
# main loop - frame by frame proceesing
while(True):
# Capture next frame
ret, frame = cap.read()
# detect end of file
if not ret:
break
# frame counter
frames = frames + 1
##############################################
# STEP 1: filter pixels between color limits
##############################################
# create NumPy arrays from the color boundaries
lower = np.array(boundaries[0], dtype = "uint8")
upper = np.array(boundaries[1], dtype = "uint8")
# create range color mas and apply
mask = cv2.inRange(frame, lower, upper)
filteredImg = cv2.bitwise_and(frame, frame, mask = mask)
#count number of not zero pixels - must be grayscale, countNonZero don't work
grayImg = cv2.cvtColor(filteredImg, cv2.COLOR_BGR2GRAY)
count = cv2.countNonZero(grayImg)
#print status
print("frame= %d\tredPixels=%d\tgeneratedFiles=%d" % (frames, count, files))
#make copy before
imageForFile=frame.copy()
###############################################
# STEP 2: Find pixels boundaries for better
# visualization
###############################################
# calculculate countours of non zeropixels
ret, threshImg = cv2.threshold(grayImg, 1, 1, 1)
im2, contours, hierarchy = cv2.findContours(threshImg, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
if(len(contours) > 1 ):
# find the outer rectangle of pixels
maxx=0
minx=5000
maxy=0
miny=5000
for contour in contours[1:]:
for point in contour:
#print(point)
x=point[0][0]
y=point[0][1]
maxx = max(x,maxx)
minx = min(x,minx)
maxy = max(y,maxy)
miny = min(y,miny)
# draw countour and boundary info to visible image - makes pixels more visible
cv2.rectangle(frame,(minx-10,miny-10),(maxx+10,maxy+10),(0,0,255),2)
cv2.drawContours(frame, contours[1:], -1, (0,0,255), 1)
# write frame with boundaries to output video file
out.write(frame)
#########################################
# STEP 3: Show frame with potential pixels and boundaries as a smaller video
#########################################
# show actual image with metadata resized to HD
imagePreview=cv2.resize(frame,(1280,720))
cv2.imshow('actualFrame',imagePreview)
##################################################################
# STEP 4: Save to file if there are more red pixels than treshold
##################################################################
if count > treshold:
# don't save every file
if frames >= nextFileFrame:
# add rectangle to image - but not pixel contours
cv2.rectangle(imageForFile,(minx,miny),(maxx,maxy),(0,255,0),2)
# image filename contains information about: source videofile actual frame and number of red pixels
jpegFileNameFull = "%s/%s/%s-%d-%d.jpg" % (basedir,outfolder,infile.replace(".","-"),count,frames)
print("New suspicious image: %s", (jpegFileNameFull))
cv2.imwrite(jpegFileNameFull,imageForFile)
files = files + 1
nextFileFrame=frames+waitUntilNextFileFrames # don't save few next frames
treshold=min(count * 1.2 ,100) # increase treshold for a while
else:
treshold=max(treshold-5, STARTTRESHOLD) # if nothing found lower theshold back to start
# wait for user input to break the cycle
if cv2.waitKey(1) & 0xFF == ord('q'):
break
# end of main loop
# When everything done, release the capture and output
cap.release()
out.release()
cv2.destroyAllWindows()
print("All done. There is %d suspicious images in %s/%s" % (files,basedir,outfolder))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment