Auto capture image everytime a pothole is detected - python

I'm starting to learn Python and I have some code here. This code already works and detects a pothole on the road using my raspberry pi 4. But my problem is that I want to make my camera capture an image every time a pothole is detected. Does anyone know how to do it? Here is the code
Start capturing video input from the camera.
cap = cv2.VideoCapture(camera_id)
cap.set(cv2.CAP_PROP_FRAME_WIDTH, width)
cap.set(cv2.CAP_PROP_FRAME_HEIGHT, height)
Visualization parameters
row_size = 20 # pixels
left_margin = 24 # pixels
text_color = (0, 0, 255) # red
font_size = 1
font_thickness = 1
fps_avg_frame_count = 10
Initialize the object detection model
base_options = core.BaseOptions(
file_name=model, use_coral=enable_edgetpu, num_threads=num_threads)
detection_options = processor.DetectionOptions(
max_results=3, score_threshold=0.3)
options = vision.ObjectDetectorOptions(
base_options=base_options, detection_options=detection_options)
detector = vision.ObjectDetector.create_from_options(options)
Continuously capture images from the camera and run inference
while cap.isOpened():
success, image = cap.read()
if not success:
sys.exit(
'ERROR: Unable to read from webcam. Please verify your webcam settings.'
)
counter += 1
image = cv2.flip(image, 1)
Run object detection estimation using the model.
detection_result = detector.detect(input_tensor)
def main():
parser = argparse.ArgumentParser(
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
parser.add_argument(
'--model',
help='Path of the object detection model.',
required=False,
default='pothole_label.tflite')
parser.add_argument(
'--cameraId', help='Id of camera.', required=False, type=int, default=0)
parser.add_argument(
'--frameWidth',
help='Width of frame to capture from camera.',
required=False,
type=int,
default=640)
parser.add_argument(
'--frameHeight',
help='Height of frame to capture from camera.',
required=False,
type=int,
default=480)
parser.add_argument(
'--numThreads',
help='Number of CPU threads to run the model.',
required=False,
type=int,
default=4)
parser.add_argument(
'--enableEdgeTPU',
help='Whether to run the model on EdgeTPU.',
action='store_true',
required=False,
default=False)
args = parser.parse_args()
run(args.model, int(args.cameraId), args.frameWidth, args.frameHeight,
int(args.numThreads), bool(args.enableEdgeTPU))
if __name__ == '__main__':
main()

You already have all the info you need.
In your case, you want to save the results of your detection.
To generally save, you would save the image from the camera at each frame as such
cv2.imwrite(f'{counter}.jpg', image)
If you want to filter the results only in the case of detection. Assuming that your detection_result is a numpy array:
if detection_result.shape[0]:
cv2.imwrite(f'{counter}.jpg', image)
This will check that you have one or more detections and save accordingly.

Related

Error implementing delaunay traingulation image morphing python

I am implementing image morphing from github in python. For that I am using delaunay triangulation, but I getting error importing libraries. I tried installing delaunay but it didn't work.
from face_landmark_detection import generate_face_correspondences
from delaunay_triangulation import make_delaunay
from face_morph import generate_morph_sequence
import subprocess
import argparse
import shutil
import os
import cv2
def doMorphing(img1, img2, duration, frame_rate, output):
[size, img1, img2, points1, points2, list3] = generate_face_correspondences(img1, img2)
if \__name_\_ == "\__main_\_":
parser = argparse.ArgumentParser()
parser.add_argument("--img1", required=True, help="The First Image")
parser.add_argument("--img2", required=True, help="The Second Image")
parser.add_argument("--duration", type=int, default=5, help="The duration")
parser.add_argument("--frame", type=int, default=20, help="The frameame Rate")
parser.add_argument("--output", help="Output Video Path")
args = parser.parse_args()
image1 = cv2.imread(args.img1)
image2 = cv2.imread(args.img2)
doMorphing(image1, image2, args.duration, args.frame, args.output)
I am implementing https://github.com/Azmarie/Face-Morphing/tree/master/code, but I am getting error implementing delaunay triangulation for image morphing.
output)

How do I pass arguments when I import the below .py script as a module?

I know how to execute it via the command line, but looking for input to execute inside another python script. I tried passing the arguments as main(-- score-thr 0.7, --show, vid, config_file, chkpnt_file). Not sure that's how to do it though. Thank you in advance for helping out!
import argparse
import cv2
import mmcv
from mmdet.apis import inference_detector, init_detector
def parse_args():
parser = argparse.ArgumentParser(description='MMDetection video demo')
parser.add_argument('video', help='Video file')
parser.add_argument('config', help='Config file')
parser.add_argument('checkpoint', help='Checkpoint file')
parser.add_argument(
'--device', default='cuda:0', help='Device used for inference')
parser.add_argument(
'--score-thr', type=float, default=0.7, help='Bbox score threshold')
parser.add_argument('--out', type=str, help='Output video file')
parser.add_argument('--show', action='store_true', help='Show video')
parser.add_argument(
'--wait-time',
type=float,
default=1,
help='The interval of show (s), 0 is block')
args = parser.parse_args()
return args
def main():
args = parse_args()
assert args.out or args.show, \
('Please specify at least one operation (save/show the '
'video) with the argument "--out" or "--show"')
model = init_detector(args.config, args.checkpoint, device=args.device)
video_reader = mmcv.VideoReader(args.video)
video_writer = None
if args.out:
fourcc = cv2.VideoWriter_fourcc(*'mp4v')
video_writer = cv2.VideoWriter(
args.out, fourcc, video_reader.fps,
(video_reader.width, video_reader.height))
for frame in mmcv.track_iter_progress(video_reader):
result = inference_detector(model, frame)
frame = model.show_result(frame, result, score_thr=args.score_thr)
if args.show:
cv2.namedWindow('video', 0)
mmcv.imshow(frame, 'video', args.wait_time)
if args.out:
video_writer.write(frame)
if video_writer:
video_writer.release()
cv2.destroyAllWindows()
if __name__ == '__main__':
main()
main() gets its arguments from sys.argv when it uses argparse. So you need to fill that in before calling it.
sys.argv = ['progname.py', '--score-thr', '0.7', '--show', vid, config_file, chkpnt_file]
main()

Running optimization process with GPU using PYTHON 3.5 and Backtrader

I was giving a try to the optimization process of the Backtrader library. I see that the code run pretty well with multi-core CPU. It took around 22.352761494772228 second for the complete optimization process. But could be even faster if worked with GPU.
Hence, I would like to know how I can run the following with GPU:
#!/usr/bin/env python
# -*- coding: utf-8; py-indent-offset:4 -*-
from __future__ import (absolute_import, division, print_function,
unicode_literals)
import argparse
import datetime
import time
from backtrader.utils.py3 import range
import backtrader as bt
import backtrader.indicators as btind
import backtrader.feeds as btfeeds
class OptimizeStrategy(bt.Strategy):
params = (('smaperiod', 15),
('macdperiod1', 12),
('macdperiod2', 26),
('macdperiod3', 9),
)
def __init__(self):
# Add indicators to add load
btind.SMA(period=self.p.smaperiod)
btind.MACD(period_me1=self.p.macdperiod1,
period_me2=self.p.macdperiod2,
period_signal=self.p.macdperiod3)
def runstrat():
args = parse_args()
# Create a cerebro entity
cerebro = bt.Cerebro(maxcpus=args.maxcpus,
runonce=not args.no_runonce,
exactbars=args.exactbars,
optdatas=not args.no_optdatas,
optreturn=not args.no_optreturn)
# Add a strategy
cerebro.optstrategy(
OptimizeStrategy,
smaperiod=range(args.ma_low, args.ma_high),
macdperiod1=range(args.m1_low, args.m1_high),
macdperiod2=range(args.m2_low, args.m2_high),
macdperiod3=range(args.m3_low, args.m3_high),
)
# Get the dates from the args
fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
# Create the 1st data
data = btfeeds.BacktraderCSVData(
dataname=args.data,
fromdate=fromdate,
todate=todate)
# Add the Data Feed to Cerebro
cerebro.adddata(data)
# clock the start of the process
tstart = time.clock()
# Run over everything
stratruns = cerebro.run()
# clock the end of the process
tend = time.clock()
print('==================================================')
for stratrun in stratruns:
print('**************************************************')
for strat in stratrun:
print('--------------------------------------------------')
print(strat.p._getkwargs())
print('==================================================')
# print out the result
print('Time used:', str(tend - tstart))
def parse_args():
parser = argparse.ArgumentParser(
description='Optimization',
formatter_class=argparse.RawTextHelpFormatter,
)
parser.add_argument(
'--data', '-d',
default='2006-day-001.txt',
help='data to add to the system')
parser.add_argument(
'--fromdate', '-f',
default='2006-01-01',
help='Starting date in YYYY-MM-DD format')
parser.add_argument(
'--todate', '-t',
default='2006-12-31',
help='Starting date in YYYY-MM-DD format')
parser.add_argument(
'--maxcpus', '-m',
type=int, required=False, default=0,
help=('Number of CPUs to use in the optimization'
'\n'
' - 0 (default): use all available CPUs\n'
' - 1 -> n: use as many as specified\n'))
parser.add_argument(
'--no-runonce', action='store_true', required=False,
help='Run in next mode')
parser.add_argument(
'--exactbars', required=False, type=int, default=0,
help=('Use the specified exactbars still compatible with preload\n'
' 0 No memory savings\n'
' -1 Moderate memory savings\n'
' -2 Less moderate memory savings\n'))
parser.add_argument(
'--no-optdatas', action='store_true', required=False,
help='Do not optimize data preloading in optimization')
parser.add_argument(
'--no-optreturn', action='store_true', required=False,
help='Do not optimize the returned values to save time')
parser.add_argument(
'--ma_low', type=int,
default=10, required=False,
help='SMA range low to optimize')
parser.add_argument(
'--ma_high', type=int,
default=30, required=False,
help='SMA range high to optimize')
parser.add_argument(
'--m1_low', type=int,
default=12, required=False,
help='MACD Fast MA range low to optimize')
parser.add_argument(
'--m1_high', type=int,
default=20, required=False,
help='MACD Fast MA range high to optimize')
parser.add_argument(
'--m2_low', type=int,
default=26, required=False,
help='MACD Slow MA range low to optimize')
parser.add_argument(
'--m2_high', type=int,
default=30, required=False,
help='MACD Slow MA range high to optimize')
parser.add_argument(
'--m3_low', type=int,
default=9, required=False,
help='MACD Signal range low to optimize')
parser.add_argument(
'--m3_high', type=int,
default=15, required=False,
help='MACD Signal range high to optimize')
return parser.parse_args()
if __name__ == '__main__':
runstrat()
The sample data used is here: Sample Data file
Let me know what improment I can make. I thought of using numba or Pycuda or PyOpenCL
I don't think this is possible for Backtrader as mentioned in their FAQs
Optimization is slow and consumes RAM
Indeed. Parameter overfitting is also a great and formidable enemy of algorithmic trading.
I want to use the GPU for optimization
Nice idea, but the multiprocessing module in Python won't do that.
https://community.backtrader.com/topic/381/faq
Cuda and all can be used in cases where you want to offload a computation to the GPU. Like below example
import numpy as np
from timeit import default_timer as timer
from numba import vectorize
#vectorize(['float32(float32, float32)'], target='cuda')
def pow(a, b):
return a ** b
def main():
vec_size = 100000000
a = b = np.array(np.random.sample(vec_size), dtype=np.float32)
c = np.zeros(vec_size, dtype=np.float32)
start = timer()
c = pow(a, b)
duration = timer() - start
print(duration)
if __name__ == '__main__':
main()
PS: Example credits to https://weeraman.com/put-that-gpu-to-good-use-with-python-e5a437168c01
It cannot be done without rewriting the framework (as opposed to rewriting your code) One of the main goals of the platform was to be pure Python and only use packages which are in the standard library.
Reference: myself (parent of the beast)
The question has been asked before and that's why there is a explicit mention in the FAQ.

OpenCV 3 VideoWriter Inserting an Extra Frames

I'm trying to write a video in OpenCV3 (Python 3.6). I found this code posted somewhere. The code works but when I play the video, it seems that every few seconds seconds or so it inserts the wrong frame. It looks like it's the first frame of the sequence. Here is how the video looks. (Link to video in case the embed code doesn't run)
<iframe width="560" height="315" src="https://www.youtube.com/embed/J3HKaQlzS8Y" frameborder="0" gesture="media" allowfullscreen></iframe>
Here is the code i'm using on my Windows 10 (64bit)
#!/usr/local/bin/python3
import cv2
import argparse
import os
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-ext", "--extension", required=False, default='jpg',
help="extension name. default is 'jpg'.")
ap.add_argument("-o", "--output", required=False, default='output.mp4',
help="output video file")
args = vars(ap.parse_args())
# Arguments
dir_path = '.'
ext = args['extension']
output = args['output']
images = []
for f in os.listdir(dir_path):
if f.endswith(ext):
images.append(f)
# Determine the width and height from the first image
image_path = os.path.join(dir_path, images[0])
frame = cv2.imread(image_path)
cv2.imshow('video',frame)
height, width, channels = frame.shape
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case
out = cv2.VideoWriter(output, fourcc, 20.0, (width, height))
for image in images:
image_path = os.path.join(dir_path, image)
frame = cv2.imread(image_path)
out.write(frame) # Write out frame to video
cv2.imshow('video',frame)
if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit
break
# Release everything if job is finished
out.release()
cv2.destroyAllWindows()
print("The output video is {}".format(output))
Any pointers would be apprecited
In your code, after this code:
images = []
for f in os.listdir(dir_path):
if f.endswith(ext):
images.append(f)
just add:
images = sorted(images, key=lambda x: (int(re.sub('\D','',x)),x))
so that we will get a sorted data. Hence the video frames will be all set in there positions. Don't forget to import re as header file.

Sequence of images to video in OpenCV + range of reading

Already fighting with this problem for a whole day, maybe anyone can help? Have a basic knowledge at Mathlab, python and openCV
I am use python for make a video from images. And, as usually, found a problem with it. There is no sequence in reading image's for writing video. For example i have img_01,img_02,.....img_n. Each img - frame of video. And at final video it's looks like:
./img_155.jpg
./img_476.jpg
./img_282.jpg
and etc.
So, it's totally chaotic at the final video, as result...
Is anyone can help, please, with this problem? I found a lot of hints, but all of them with c++ only. There is code, what i am using now:
import cv2
import argparse
import os
# Construct the argument parser and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-ext", "--extension", required=False, default='jpg', help="extension name. default is 'png'.")
ap.add_argument("-o", "--output", required=False, default='output.mp4', help="output video file")
args = vars(ap.parse_args())
# Arguments
dir_path = '.'
ext = args['extension']
output = args['output']
images = []
for f in os.listdir(dir_path):
if f.endswith(ext):
images.append(f)
# Determine the width and height from the first image
image_path = os.path.join(dir_path, images[0])
frame = cv2.imread(image_path)
cv2.imshow('video',frame)
height, width, channels = frame.shape
# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'mp4v') # Be sure to use lower case
out = cv2.VideoWriter(output, fourcc, 30.0, (width, height))
for image in images:
image_path = os.path.join(dir_path, image)
frame = cv2.imread(image_path)
out.write(frame) # Write out frame to video
cv2.imshow('video',frame)
if (cv2.waitKey(1) & 0xFF) == ord('q'): # Hit `q` to exit
break
# Release everything if job is finished
out.release()
cv2.destroyAllWindows()
print("The output video is {}".format(output))
I think your problem is : for f in os.listdir(dir_path): return file name in random sequence.
You should add follow line before '# Determine the width and height from the first image'
def name2num(name):
m = re.search('img_(\d+)\.?.*', name)
return int(m.group(1),10)
images.sort(key=name2num)

Categories

Resources