vendor: OpenCV 5.0.0 snapshot at 40738fb16ceddb5fb3fea747585f7ce6abb0605b
This commit is contained in:
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Camshift tracker
|
||||
================
|
||||
|
||||
This is a demo that shows mean-shift based tracking
|
||||
You select a color objects such as your face and it tracks it.
|
||||
This reads from video camera (0 by default, or the camera number the user enters)
|
||||
|
||||
[1] http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.14.7673
|
||||
|
||||
Usage:
|
||||
------
|
||||
camshift.py [<video source>]
|
||||
|
||||
To initialize tracking, select the object with mouse
|
||||
|
||||
Keys:
|
||||
-----
|
||||
ESC - exit
|
||||
b - toggle back-projected probability visualization
|
||||
'''
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
# local module
|
||||
import video
|
||||
from video import presets
|
||||
|
||||
|
||||
class App(object):
|
||||
def __init__(self, video_src):
|
||||
self.cam = video.create_capture(video_src, presets['cube'])
|
||||
_ret, self.frame = self.cam.read()
|
||||
cv.namedWindow('camshift')
|
||||
cv.setMouseCallback('camshift', self.onmouse)
|
||||
|
||||
self.selection = None
|
||||
self.drag_start = None
|
||||
self.show_backproj = False
|
||||
self.track_window = None
|
||||
|
||||
def onmouse(self, event, x, y, flags, param):
|
||||
if event == cv.EVENT_LBUTTONDOWN:
|
||||
self.drag_start = (x, y)
|
||||
self.track_window = None
|
||||
if self.drag_start:
|
||||
xmin = min(x, self.drag_start[0])
|
||||
ymin = min(y, self.drag_start[1])
|
||||
xmax = max(x, self.drag_start[0])
|
||||
ymax = max(y, self.drag_start[1])
|
||||
self.selection = (xmin, ymin, xmax, ymax)
|
||||
if event == cv.EVENT_LBUTTONUP:
|
||||
self.drag_start = None
|
||||
self.track_window = (xmin, ymin, xmax - xmin, ymax - ymin)
|
||||
|
||||
def show_hist(self):
|
||||
bin_count = self.hist.shape[0]
|
||||
bin_w = 24
|
||||
img = np.zeros((256, bin_count*bin_w, 3), np.uint8)
|
||||
for i in range(bin_count):
|
||||
h = int(self.hist[i])
|
||||
cv.rectangle(img, (i*bin_w+2, 255), ((i+1)*bin_w-2, 255-h), (int(180.0*i/bin_count), 255, 255), -1)
|
||||
img = cv.cvtColor(img, cv.COLOR_HSV2BGR)
|
||||
cv.imshow('hist', img)
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
_ret, self.frame = self.cam.read()
|
||||
vis = self.frame.copy()
|
||||
hsv = cv.cvtColor(self.frame, cv.COLOR_BGR2HSV)
|
||||
mask = cv.inRange(hsv, np.array((0., 60., 32.)), np.array((180., 255., 255.)))
|
||||
|
||||
if self.selection:
|
||||
x0, y0, x1, y1 = self.selection
|
||||
hsv_roi = hsv[y0:y1, x0:x1]
|
||||
mask_roi = mask[y0:y1, x0:x1]
|
||||
hist = cv.calcHist( [hsv_roi], [0], mask_roi, [16], [0, 180] )
|
||||
cv.normalize(hist, hist, 0, 255, cv.NORM_MINMAX)
|
||||
self.hist = hist.reshape(-1)
|
||||
self.show_hist()
|
||||
|
||||
vis_roi = vis[y0:y1, x0:x1]
|
||||
cv.bitwise_not(vis_roi, vis_roi)
|
||||
vis[mask == 0] = 0
|
||||
|
||||
if self.track_window and self.track_window[2] > 0 and self.track_window[3] > 0:
|
||||
self.selection = None
|
||||
prob = cv.calcBackProject([hsv], [0], self.hist, [0, 180], 1)
|
||||
prob &= mask
|
||||
term_crit = ( cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 1 )
|
||||
track_box, self.track_window = cv.CamShift(prob, self.track_window, term_crit)
|
||||
|
||||
if self.show_backproj:
|
||||
vis[:] = prob[...,np.newaxis]
|
||||
try:
|
||||
cv.ellipse(vis, track_box, (0, 0, 255), 2)
|
||||
except:
|
||||
print(track_box)
|
||||
|
||||
cv.imshow('camshift', vis)
|
||||
|
||||
ch = cv.waitKey(5)
|
||||
if ch == 27:
|
||||
break
|
||||
if ch == ord('b'):
|
||||
self.show_backproj = not self.show_backproj
|
||||
cv.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
import sys
|
||||
try:
|
||||
video_src = sys.argv[1]
|
||||
except:
|
||||
video_src = 0
|
||||
App(video_src).run()
|
||||
@@ -0,0 +1,83 @@
|
||||
#!/usr/bin/env python3
|
||||
# This file is part of OpenCV project.
|
||||
# It is subject to the license terms in the LICENSE file found in the top-level directory
|
||||
# of this distribution and at http://opencv.org/license.html
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
import cv2 as cv
|
||||
|
||||
USAGE = """\
|
||||
Chromatic Aberration Correction Sample
|
||||
Usage:
|
||||
chromatic_aberration_correction.py <input_image> <calibration_file> [--bayer <code>] [--output <path>]
|
||||
|
||||
Arguments:
|
||||
input_image Path to the input image. Can be:
|
||||
• a 3-channel BGR image, or
|
||||
• a 1-channel raw Bayer image (see bayer_pattern)
|
||||
calibration_file OpenCV YAML/XML file with chromatic aberration calibration:
|
||||
image_width, image_height, red_channel/coeffs_x, coeffs_y,
|
||||
blue_channel/coeffs_x, coeffs_y.
|
||||
output (optional) Path to save the corrected image. Default: corrected.png
|
||||
bayer (optional) integer code for demosaicing a 1-channel raw image
|
||||
If omitted or <0, input is assumed 3-channel BGR.
|
||||
|
||||
Example:
|
||||
python chromatic_aberration_correction.py input.png calib.yaml --bayer 46 --output corrected.png
|
||||
"""
|
||||
|
||||
def main(argv=None):
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Chromatic Aberration Correction Sample",
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=USAGE
|
||||
)
|
||||
parser.add_argument("input", help="Input image (BGR or Bayer)")
|
||||
parser.add_argument("calibration", help="Calibration file (YAML/XML)")
|
||||
parser.add_argument("--output", default="corrected.png", help="Output image file")
|
||||
parser.add_argument("--bayer", type=int, default=-1, help="Bayer pattern code for demosaic")
|
||||
parser.add_argument("--no-gui", action="store_true", help="Do not open image windows")
|
||||
|
||||
args = parser.parse_args(argv)
|
||||
|
||||
img = cv.imread(args.input, cv.IMREAD_UNCHANGED)
|
||||
if img is None:
|
||||
print(f"ERROR: Could not load input image: {args.input}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
fs = cv.FileStorage(args.calibration, cv.FileStorage_READ)
|
||||
if not fs.isOpened():
|
||||
print(f"Could not calibration coefficients from {args.calibration}")
|
||||
return 1
|
||||
|
||||
try:
|
||||
coeffMat, size, degree = cv.loadChromaticAberrationParams(fs.root())
|
||||
corrected = cv.correctChromaticAberration(img, coeffMat, size, degree, args.bayer)
|
||||
|
||||
if corrected is None:
|
||||
print("ERROR: cv.correctChromaticAberration returned None", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if not args.no_gui:
|
||||
cv.namedWindow("Original", cv.WINDOW_AUTOSIZE)
|
||||
cv.namedWindow("Corrected", cv.WINDOW_AUTOSIZE)
|
||||
cv.imshow("Original", img)
|
||||
cv.imshow("Corrected", corrected)
|
||||
print("Press any key to continue...")
|
||||
cv.waitKey(0)
|
||||
cv.destroyAllWindows()
|
||||
|
||||
if not cv.imwrite(args.output, corrected):
|
||||
print(f"WARNING: Could not write output image: {args.output}", file=sys.stderr)
|
||||
else:
|
||||
print(f"Saved corrected image to: {args.output}")
|
||||
|
||||
except cv.error as e:
|
||||
print(f"OpenCV error: {e}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
return 0
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
This program illustrates the use of findContours and drawContours.
|
||||
The original image is put up along with the image of drawn contours.
|
||||
|
||||
Usage:
|
||||
contours.py
|
||||
A trackbar is put up which controls the contour level from -3 to 3
|
||||
'''
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
def make_image():
|
||||
img = np.zeros((500, 500), np.uint8)
|
||||
black, white = 0, 255
|
||||
for i in range(6):
|
||||
dx = int((i%2)*250 - 30)
|
||||
dy = int((i/2.)*150)
|
||||
|
||||
if i == 0:
|
||||
for j in range(11):
|
||||
angle = (j+5)*np.pi/21
|
||||
c, s = np.cos(angle), np.sin(angle)
|
||||
x1, y1 = np.int32([dx+100+j*10-80*c, dy+100-90*s])
|
||||
x2, y2 = np.int32([dx+100+j*10-30*c, dy+100-30*s])
|
||||
cv.line(img, (x1, y1), (x2, y2), white)
|
||||
|
||||
cv.ellipse( img, (dx+150, dy+100), (100,70), 0, 0, 360, white, -1 )
|
||||
cv.ellipse( img, (dx+115, dy+70), (30,20), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+185, dy+70), (30,20), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+115, dy+70), (15,15), 0, 0, 360, white, -1 )
|
||||
cv.ellipse( img, (dx+185, dy+70), (15,15), 0, 0, 360, white, -1 )
|
||||
cv.ellipse( img, (dx+115, dy+70), (5,5), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+185, dy+70), (5,5), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+150, dy+100), (10,5), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+150, dy+150), (40,10), 0, 0, 360, black, -1 )
|
||||
cv.ellipse( img, (dx+27, dy+100), (20,35), 0, 0, 360, white, -1 )
|
||||
cv.ellipse( img, (dx+273, dy+100), (20,35), 0, 0, 360, white, -1 )
|
||||
return img
|
||||
|
||||
def main():
|
||||
img = make_image()
|
||||
h, w = img.shape[:2]
|
||||
|
||||
contours0, hierarchy = cv.findContours( img.copy(), cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
|
||||
contours = [cv.approxPolyDP(cnt, 3, True) for cnt in contours0]
|
||||
|
||||
def update(levels):
|
||||
vis = np.zeros((h, w, 3), np.uint8)
|
||||
levels = levels - 3
|
||||
cv.drawContours( vis, contours, (-1, 2)[levels <= 0], (128,255,255),
|
||||
3, cv.LINE_AA, hierarchy, abs(levels) )
|
||||
cv.imshow('contours', vis)
|
||||
update(3)
|
||||
cv.createTrackbar( "levels+3", "contours", 3, 7, update )
|
||||
cv.imshow('image', img)
|
||||
cv.waitKey()
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+120
@@ -0,0 +1,120 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
sample for discrete fourier transform (dft)
|
||||
|
||||
USAGE:
|
||||
dft.py <image_file>
|
||||
'''
|
||||
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import sys
|
||||
|
||||
|
||||
def shift_dft(src, dst=None):
|
||||
'''
|
||||
Rearrange the quadrants of Fourier image so that the origin is at
|
||||
the image center. Swaps quadrant 1 with 3, and 2 with 4.
|
||||
|
||||
src and dst arrays must be equal size & type
|
||||
'''
|
||||
|
||||
if dst is None:
|
||||
dst = np.empty(src.shape, src.dtype)
|
||||
elif src.shape != dst.shape:
|
||||
raise ValueError("src and dst must have equal sizes")
|
||||
elif src.dtype != dst.dtype:
|
||||
raise TypeError("src and dst must have equal types")
|
||||
|
||||
if src is dst:
|
||||
ret = np.empty(src.shape, src.dtype)
|
||||
else:
|
||||
ret = dst
|
||||
|
||||
h, w = src.shape[:2]
|
||||
|
||||
cx1 = cx2 = w // 2
|
||||
cy1 = cy2 = h // 2
|
||||
|
||||
# if the size is odd, then adjust the bottom/right quadrants
|
||||
if w % 2 != 0:
|
||||
cx2 += 1
|
||||
if h % 2 != 0:
|
||||
cy2 += 1
|
||||
|
||||
# swap quadrants
|
||||
|
||||
# swap q1 and q3
|
||||
ret[h-cy1:, w-cx1:] = src[0:cy1 , 0:cx1 ] # q1 -> q3
|
||||
ret[0:cy2 , 0:cx2 ] = src[h-cy2:, w-cx2:] # q3 -> q1
|
||||
|
||||
# swap q2 and q4
|
||||
ret[0:cy2 , w-cx2:] = src[h-cy2:, 0:cx2 ] # q2 -> q4
|
||||
ret[h-cy1:, 0:cx1 ] = src[0:cy1 , w-cx1:] # q4 -> q2
|
||||
|
||||
if src is dst:
|
||||
dst[:,:] = ret
|
||||
|
||||
return dst
|
||||
|
||||
|
||||
def main():
|
||||
if len(sys.argv) > 1:
|
||||
fname = sys.argv[1]
|
||||
else:
|
||||
fname = 'baboon.jpg'
|
||||
print("usage : python dft.py <image_file>")
|
||||
|
||||
im = cv.imread(cv.samples.findFile(fname))
|
||||
|
||||
# convert to grayscale
|
||||
im = cv.cvtColor(im, cv.COLOR_BGR2GRAY)
|
||||
h, w = im.shape[:2]
|
||||
|
||||
realInput = im.astype(np.float64)
|
||||
|
||||
# perform an optimally sized dft
|
||||
dft_M = cv.getOptimalDFTSize(w)
|
||||
dft_N = cv.getOptimalDFTSize(h)
|
||||
|
||||
# copy A to dft_A and pad dft_A with zeros
|
||||
dft_A = np.zeros((dft_N, dft_M, 2), dtype=np.float64)
|
||||
dft_A[:h, :w, 0] = realInput
|
||||
|
||||
# no need to pad bottom part of dft_A with zeros because of
|
||||
# use of nonzeroRows parameter in cv.dft()
|
||||
cv.dft(dft_A, dst=dft_A, nonzeroRows=h)
|
||||
|
||||
cv.imshow("win", im)
|
||||
|
||||
# Split fourier into real and imaginary parts
|
||||
image_Re, image_Im = cv.split(dft_A)
|
||||
|
||||
# Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
|
||||
magnitude = cv.sqrt(image_Re**2.0 + image_Im**2.0)
|
||||
|
||||
# Compute log(1 + Mag)
|
||||
log_spectrum = cv.log(1.0 + magnitude)
|
||||
|
||||
# Rearrange the quadrants of Fourier image so that the origin is at
|
||||
# the image center
|
||||
shift_dft(log_spectrum, log_spectrum)
|
||||
|
||||
# normalize and display the results as rgb
|
||||
cv.normalize(log_spectrum, log_spectrum, 0.0, 1.0, cv.NORM_MINMAX)
|
||||
cv.imshow("magnitude", log_spectrum)
|
||||
|
||||
cv.waitKey(0)
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+122
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
example to show optical flow estimation using DISOpticalFlow
|
||||
|
||||
USAGE: dis_opt_flow.py [<video_source>]
|
||||
|
||||
Keys:
|
||||
1 - toggle HSV flow visualization
|
||||
2 - toggle glitch
|
||||
3 - toggle spatial propagation of flow vectors
|
||||
4 - toggle temporal propagation of flow vectors
|
||||
ESC - exit
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import video
|
||||
|
||||
|
||||
def draw_flow(img, flow, step=16):
|
||||
h, w = img.shape[:2]
|
||||
y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
|
||||
fx, fy = flow[y,x].T
|
||||
lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
|
||||
lines = np.int32(lines + 0.5)
|
||||
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
|
||||
cv.polylines(vis, lines, 0, (0, 255, 0))
|
||||
for (x1, y1), (_x2, _y2) in lines:
|
||||
cv.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
|
||||
return vis
|
||||
|
||||
|
||||
def draw_hsv(flow):
|
||||
h, w = flow.shape[:2]
|
||||
fx, fy = flow[:,:,0], flow[:,:,1]
|
||||
ang = np.arctan2(fy, fx) + np.pi
|
||||
v = np.sqrt(fx*fx+fy*fy)
|
||||
hsv = np.zeros((h, w, 3), np.uint8)
|
||||
hsv[...,0] = ang*(180/np.pi/2)
|
||||
hsv[...,1] = 255
|
||||
hsv[...,2] = np.minimum(v*4, 255)
|
||||
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
|
||||
return bgr
|
||||
|
||||
|
||||
def warp_flow(img, flow):
|
||||
h, w = flow.shape[:2]
|
||||
flow = -flow
|
||||
flow[:,:,0] += np.arange(w)
|
||||
flow[:,:,1] += np.arange(h)[:,np.newaxis]
|
||||
res = cv.remap(img, flow, None, cv.INTER_LINEAR)
|
||||
return res
|
||||
|
||||
|
||||
def main():
|
||||
import sys
|
||||
print(__doc__)
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except IndexError:
|
||||
fn = 0
|
||||
|
||||
cam = video.create_capture(fn)
|
||||
_ret, prev = cam.read()
|
||||
prevgray = cv.cvtColor(prev, cv.COLOR_BGR2GRAY)
|
||||
show_hsv = False
|
||||
show_glitch = False
|
||||
use_spatial_propagation = False
|
||||
use_temporal_propagation = True
|
||||
cur_glitch = prev.copy()
|
||||
inst = cv.DISOpticalFlow.create(cv.DISOPTICAL_FLOW_PRESET_MEDIUM)
|
||||
inst.setUseSpatialPropagation(use_spatial_propagation)
|
||||
|
||||
flow = None
|
||||
while True:
|
||||
_ret, img = cam.read()
|
||||
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||
if flow is not None and use_temporal_propagation:
|
||||
#warp previous flow to get an initial approximation for the current flow:
|
||||
flow = inst.calc(prevgray, gray, warp_flow(flow,flow))
|
||||
else:
|
||||
flow = inst.calc(prevgray, gray, None)
|
||||
prevgray = gray
|
||||
|
||||
cv.imshow('flow', draw_flow(gray, flow))
|
||||
if show_hsv:
|
||||
cv.imshow('flow HSV', draw_hsv(flow))
|
||||
if show_glitch:
|
||||
cur_glitch = warp_flow(cur_glitch, flow)
|
||||
cv.imshow('glitch', cur_glitch)
|
||||
|
||||
ch = 0xFF & cv.waitKey(5)
|
||||
if ch == 27:
|
||||
break
|
||||
if ch == ord('1'):
|
||||
show_hsv = not show_hsv
|
||||
print('HSV flow visualization is', ['off', 'on'][show_hsv])
|
||||
if ch == ord('2'):
|
||||
show_glitch = not show_glitch
|
||||
if show_glitch:
|
||||
cur_glitch = img.copy()
|
||||
print('glitch is', ['off', 'on'][show_glitch])
|
||||
if ch == ord('3'):
|
||||
use_spatial_propagation = not use_spatial_propagation
|
||||
inst.setUseSpatialPropagation(use_spatial_propagation)
|
||||
print('spatial propagation is', ['off', 'on'][use_spatial_propagation])
|
||||
if ch == ord('4'):
|
||||
use_temporal_propagation = not use_temporal_propagation
|
||||
print('temporal propagation is', ['off', 'on'][use_temporal_propagation])
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Distance transform sample.
|
||||
|
||||
Usage:
|
||||
distrans.py [<image>]
|
||||
|
||||
Keys:
|
||||
ESC - exit
|
||||
v - toggle voronoi mode
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
from common import make_cmap
|
||||
|
||||
def main():
|
||||
import sys
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except:
|
||||
fn = 'fruits.jpg'
|
||||
|
||||
fn = cv.samples.findFile(fn)
|
||||
img = cv.imread(fn, cv.IMREAD_GRAYSCALE)
|
||||
if img is None:
|
||||
print('Failed to load fn:', fn)
|
||||
sys.exit(1)
|
||||
|
||||
cm = make_cmap('jet')
|
||||
need_update = True
|
||||
voronoi = False
|
||||
|
||||
def update(dummy=None):
|
||||
global need_update
|
||||
need_update = False
|
||||
thrs = cv.getTrackbarPos('threshold', 'distrans')
|
||||
mark = cv.Canny(img, thrs, 3*thrs)
|
||||
dist, labels = cv.distanceTransformWithLabels(~mark, cv.DIST_L2, 5)
|
||||
if voronoi:
|
||||
vis = cm[np.uint8(labels)]
|
||||
else:
|
||||
vis = cm[np.uint8(dist*2)]
|
||||
vis[mark != 0] = 255
|
||||
cv.imshow('distrans', vis)
|
||||
|
||||
def invalidate(dummy=None):
|
||||
global need_update
|
||||
need_update = True
|
||||
|
||||
cv.namedWindow('distrans')
|
||||
cv.createTrackbar('threshold', 'distrans', 60, 255, invalidate)
|
||||
update()
|
||||
|
||||
|
||||
while True:
|
||||
ch = cv.waitKey(50)
|
||||
if ch == 27:
|
||||
break
|
||||
if ch == ord('v'):
|
||||
voronoi = not voronoi
|
||||
print('showing', ['distance', 'voronoi'][voronoi])
|
||||
update()
|
||||
if need_update:
|
||||
update()
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+94
@@ -0,0 +1,94 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Robust line fitting.
|
||||
==================
|
||||
|
||||
Example of using cv.fitLine function for fitting line
|
||||
to points in presence of outliers.
|
||||
|
||||
Usage
|
||||
-----
|
||||
fitline.py
|
||||
|
||||
Switch through different M-estimator functions and see,
|
||||
how well the robust functions fit the line even
|
||||
in case of ~50% of outliers.
|
||||
|
||||
Keys
|
||||
----
|
||||
SPACE - generate random points
|
||||
f - change distance function
|
||||
ESC - exit
|
||||
'''
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
# built-in modules
|
||||
import itertools as it
|
||||
|
||||
# local modules
|
||||
from common import draw_str
|
||||
|
||||
|
||||
w, h = 512, 256
|
||||
|
||||
def toint(p):
|
||||
return tuple(map(int, p))
|
||||
|
||||
def sample_line(p1, p2, n, noise=0.0):
|
||||
p1 = np.float32(p1)
|
||||
t = np.random.rand(n,1)
|
||||
return p1 + (p2-p1)*t + np.random.normal(size=(n, 2))*noise
|
||||
|
||||
dist_func_names = it.cycle('DIST_L2 DIST_L1 DIST_L12 DIST_FAIR DIST_WELSCH DIST_HUBER'.split())
|
||||
|
||||
cur_func_name = next(dist_func_names)
|
||||
|
||||
def update(_=None):
|
||||
noise = cv.getTrackbarPos('noise', 'fit line')
|
||||
n = cv.getTrackbarPos('point n', 'fit line')
|
||||
r = cv.getTrackbarPos('outlier %', 'fit line') / 100.0
|
||||
outn = int(n*r)
|
||||
|
||||
p0, p1 = (90, 80), (w-90, h-80)
|
||||
img = np.zeros((h, w, 3), np.uint8)
|
||||
cv.line(img, toint(p0), toint(p1), (0, 255, 0))
|
||||
|
||||
if n > 0:
|
||||
line_points = sample_line(p0, p1, n-outn, noise)
|
||||
outliers = np.random.rand(outn, 2) * (w, h)
|
||||
points = np.vstack([line_points, outliers])
|
||||
for p in line_points:
|
||||
cv.circle(img, toint(p), 2, (255, 255, 255), -1)
|
||||
for p in outliers:
|
||||
cv.circle(img, toint(p), 2, (64, 64, 255), -1)
|
||||
func = getattr(cv, cur_func_name)
|
||||
vx, vy, cx, cy = cv.fitLine(np.float32(points), func, 0, 0.01, 0.01)
|
||||
cv.line(img, (int(cx-vx*w), int(cy-vy*w)), (int(cx+vx*w), int(cy+vy*w)), (0, 0, 255))
|
||||
|
||||
draw_str(img, (20, 20), cur_func_name)
|
||||
cv.imshow('fit line', img)
|
||||
|
||||
def main():
|
||||
cv.namedWindow('fit line')
|
||||
cv.createTrackbar('noise', 'fit line', 3, 50, update)
|
||||
cv.createTrackbar('point n', 'fit line', 100, 500, update)
|
||||
cv.createTrackbar('outlier %', 'fit line', 30, 100, update)
|
||||
while True:
|
||||
update()
|
||||
ch = cv.waitKey(0)
|
||||
if ch == ord('f'):
|
||||
global cur_func_name
|
||||
cur_func_name = next(dist_func_names)
|
||||
if ch == 27:
|
||||
break
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
'''
|
||||
This example illustrates how to use cv.HoughCircles() function.
|
||||
|
||||
Usage:
|
||||
houghcircles.py [<image_name>]
|
||||
image argument defaults to board.jpg
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import sys
|
||||
|
||||
def main():
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except IndexError:
|
||||
fn = 'board.jpg'
|
||||
|
||||
src = cv.imread(cv.samples.findFile(fn))
|
||||
img = cv.cvtColor(src, cv.COLOR_BGR2GRAY)
|
||||
img = cv.medianBlur(img, 5)
|
||||
cimg = src.copy() # numpy function
|
||||
|
||||
circles = cv.HoughCircles(img, cv.HOUGH_GRADIENT, 1, 10, np.array([]), 200, 30, 5, 30)
|
||||
|
||||
if circles is not None: # Check if circles have been found and only then iterate over these and add them to the image
|
||||
circles = np.uint16(np.around(circles))
|
||||
_a, b, _c = circles.shape
|
||||
for i in range(b):
|
||||
cv.circle(cimg, (circles[0][i][0], circles[0][i][1]), circles[0][i][2], (0, 0, 255), 3, cv.LINE_AA)
|
||||
cv.circle(cimg, (circles[0][i][0], circles[0][i][1]), 2, (0, 255, 0), 3, cv.LINE_AA) # draw center of circle
|
||||
|
||||
cv.imshow("detected circles", cimg)
|
||||
|
||||
cv.imshow("source", src)
|
||||
cv.waitKey(0)
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
'''
|
||||
This example illustrates how to use Hough Transform to find lines
|
||||
|
||||
Usage:
|
||||
houghlines.py [<image_name>]
|
||||
image argument defaults to pic1.png
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import cv2 as cv
|
||||
import numpy as np
|
||||
|
||||
import sys
|
||||
import math
|
||||
|
||||
def main():
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except IndexError:
|
||||
fn = 'pic1.png'
|
||||
|
||||
src = cv.imread(cv.samples.findFile(fn))
|
||||
dst = cv.Canny(src, 50, 200)
|
||||
cdst = cv.cvtColor(dst, cv.COLOR_GRAY2BGR)
|
||||
|
||||
if True: # HoughLinesP
|
||||
lines = cv.HoughLinesP(dst, 1, math.pi/180.0, 40, np.array([]), 50, 10)
|
||||
a, b, _c = lines.shape
|
||||
for i in range(a):
|
||||
cv.line(cdst, (lines[i][0][0], lines[i][0][1]), (lines[i][0][2], lines[i][0][3]), (0, 0, 255), 3, cv.LINE_AA)
|
||||
|
||||
else: # HoughLines
|
||||
lines = cv.HoughLines(dst, 1, math.pi/180.0, 50, np.array([]), 0, 0)
|
||||
if lines is not None:
|
||||
a, b, _c = lines.shape
|
||||
for i in range(a):
|
||||
rho = lines[i][0][0]
|
||||
theta = lines[i][0][1]
|
||||
a = math.cos(theta)
|
||||
b = math.sin(theta)
|
||||
x0, y0 = a*rho, b*rho
|
||||
pt1 = ( int(x0+1000*(-b)), int(y0+1000*(a)) )
|
||||
pt2 = ( int(x0-1000*(-b)), int(y0-1000*(a)) )
|
||||
cv.line(cdst, pt1, pt2, (0, 0, 255), 3, cv.LINE_AA)
|
||||
|
||||
cv.imshow("detected lines", cdst)
|
||||
|
||||
cv.imshow("source", src)
|
||||
cv.waitKey(0)
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+98
@@ -0,0 +1,98 @@
|
||||
#!/usr/bin/env python
|
||||
"""
|
||||
Tracking of rotating point.
|
||||
Point moves in a circle and is characterized by a 1D state.
|
||||
state_k+1 = state_k + speed + process_noise N(0, 1e-5)
|
||||
The speed is constant.
|
||||
Both state and measurements vectors are 1D (a point angle),
|
||||
Measurement is the real state + gaussian noise N(0, 1e-1).
|
||||
The real and the measured points are connected with red line segment,
|
||||
the real and the estimated points are connected with yellow line segment,
|
||||
the real and the corrected estimated points are connected with green line segment.
|
||||
(if Kalman filter works correctly,
|
||||
the yellow segment should be shorter than the red one and
|
||||
the green segment should be shorter than the yellow one).
|
||||
Pressing any key (except ESC) will reset the tracking.
|
||||
Pressing ESC will stop the program.
|
||||
"""
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
from math import cos, sin, sqrt, pi
|
||||
|
||||
def main():
|
||||
img_height = 500
|
||||
img_width = 500
|
||||
kalman = cv.KalmanFilter(2, 1, 0)
|
||||
|
||||
code = -1
|
||||
num_circle_steps = 12
|
||||
while True:
|
||||
img = np.zeros((img_height, img_width, 3), np.uint8)
|
||||
state = np.array([[0.0],[(2 * pi) / num_circle_steps]]) # start state
|
||||
kalman.transitionMatrix = np.array([[1., 1.], [0., 1.]]) # F. input
|
||||
kalman.measurementMatrix = 1. * np.eye(1, 2) # H. input
|
||||
kalman.processNoiseCov = 1e-5 * np.eye(2) # Q. input
|
||||
kalman.measurementNoiseCov = 1e-1 * np.ones((1, 1)) # R. input
|
||||
kalman.errorCovPost = 1. * np.eye(2, 2) # P._k|k KF state var
|
||||
kalman.statePost = 0.1 * np.random.randn(2, 1) # x^_k|k KF state var
|
||||
|
||||
while True:
|
||||
def calc_point(angle):
|
||||
return (np.around(img_width / 2. + img_width / 3.0 * cos(angle), 0).astype(int),
|
||||
np.around(img_height / 2. - img_width / 3.0 * sin(angle), 1).astype(int))
|
||||
img = img * 1e-3
|
||||
state_angle = state[0, 0]
|
||||
state_pt = calc_point(state_angle)
|
||||
# advance Kalman filter to next timestep
|
||||
# updates statePre, statePost, errorCovPre, errorCovPost
|
||||
# k-> k+1, x'(k) = A*x(k)
|
||||
# P'(k) = temp1*At + Q
|
||||
prediction = kalman.predict()
|
||||
|
||||
predict_pt = calc_point(prediction[0, 0]) # equivalent to calc_point(kalman.statePre[0,0])
|
||||
# generate measurement
|
||||
measurement = kalman.measurementNoiseCov * np.random.randn(1, 1)
|
||||
measurement = np.dot(kalman.measurementMatrix, state) + measurement
|
||||
|
||||
measurement_angle = measurement[0, 0]
|
||||
measurement_pt = calc_point(measurement_angle)
|
||||
|
||||
# correct the state estimates based on measurements
|
||||
# updates statePost & errorCovPost
|
||||
kalman.correct(measurement)
|
||||
improved_pt = calc_point(kalman.statePost[0, 0])
|
||||
|
||||
# plot points
|
||||
cv.drawMarker(img, measurement_pt, (0, 0, 255), cv.MARKER_SQUARE, 5, 2)
|
||||
cv.drawMarker(img, predict_pt, (0, 255, 255), cv.MARKER_SQUARE, 5, 2)
|
||||
cv.drawMarker(img, improved_pt, (0, 255, 0), cv.MARKER_SQUARE, 5, 2)
|
||||
cv.drawMarker(img, state_pt, (255, 255, 255), cv.MARKER_STAR, 10, 1)
|
||||
# forecast one step
|
||||
cv.drawMarker(img, calc_point(np.dot(kalman.transitionMatrix, kalman.statePost)[0, 0]),
|
||||
(255, 255, 0), cv.MARKER_SQUARE, 12, 1)
|
||||
|
||||
cv.line(img, state_pt, measurement_pt, (0, 0, 255), 1, cv.LINE_AA, 0) # red measurement error
|
||||
cv.line(img, state_pt, predict_pt, (0, 255, 255), 1, cv.LINE_AA, 0) # yellow pre-meas error
|
||||
cv.line(img, state_pt, improved_pt, (0, 255, 0), 1, cv.LINE_AA, 0) # green post-meas error
|
||||
|
||||
# update the real process
|
||||
process_noise = sqrt(kalman.processNoiseCov[0, 0]) * np.random.randn(2, 1)
|
||||
state = np.dot(kalman.transitionMatrix, state) + process_noise # x_k+1 = F x_k + w_k
|
||||
|
||||
cv.imshow("Kalman", img)
|
||||
code = cv.waitKey(1000)
|
||||
if code != -1:
|
||||
break
|
||||
|
||||
if code in [27, ord('q'), ord('Q')]:
|
||||
break
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
K-means clusterization sample.
|
||||
Usage:
|
||||
kmeans.py
|
||||
|
||||
Keyboard shortcuts:
|
||||
ESC - exit
|
||||
space - generate new distribution
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
from gaussian_mix import make_gaussians
|
||||
|
||||
def main():
|
||||
cluster_n = 5
|
||||
img_size = 512
|
||||
|
||||
# generating bright palette
|
||||
colors = np.zeros((1, cluster_n, 3), np.uint8)
|
||||
colors[0,:] = 255
|
||||
colors[0,:,0] = np.arange(0, 180, 180.0/cluster_n)
|
||||
colors = cv.cvtColor(colors, cv.COLOR_HSV2BGR)[0]
|
||||
|
||||
while True:
|
||||
print('sampling distributions...')
|
||||
points, _ = make_gaussians(cluster_n, img_size)
|
||||
|
||||
term_crit = (cv.TERM_CRITERIA_EPS, 30, 0.1)
|
||||
_ret, labels, _centers = cv.kmeans(points, cluster_n, None, term_crit, 10, 0)
|
||||
|
||||
img = np.zeros((img_size, img_size, 3), np.uint8)
|
||||
for (x, y), label in zip(np.int32(points), labels.ravel()):
|
||||
c = list(map(int, colors[label]))
|
||||
|
||||
cv.circle(img, (x, y), 1, c, -1)
|
||||
|
||||
cv.imshow('kmeans', img)
|
||||
ch = cv.waitKey(0)
|
||||
if ch == 27:
|
||||
break
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
@@ -0,0 +1,69 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
This program demonstrates Laplace point/edge detection using
|
||||
OpenCV function Laplacian()
|
||||
It captures from the camera of your choice: 0, 1, ... default 0
|
||||
Usage:
|
||||
python laplace.py <ddepth> <smoothType> <sigma>
|
||||
If no arguments given default arguments will be used.
|
||||
|
||||
Keyboard Shortcuts:
|
||||
Press space bar to exit the program.
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
import sys
|
||||
|
||||
def main():
|
||||
# Declare the variables we are going to use
|
||||
ddepth = cv.CV_16S
|
||||
smoothType = "MedianBlur"
|
||||
sigma = 3
|
||||
if len(sys.argv)==4:
|
||||
ddepth = sys.argv[1]
|
||||
smoothType = sys.argv[2]
|
||||
sigma = sys.argv[3]
|
||||
# Taking input from the camera
|
||||
cap=cv.VideoCapture(0)
|
||||
# Create Window and Trackbar
|
||||
cv.namedWindow("Laplace of Image", cv.WINDOW_AUTOSIZE)
|
||||
cv.createTrackbar("Kernel Size Bar", "Laplace of Image", sigma, 15, lambda x:x)
|
||||
# Printing frame width, height and FPS
|
||||
print("=="*40)
|
||||
print("Frame Width: ", cap.get(cv.CAP_PROP_FRAME_WIDTH), "Frame Height: ", cap.get(cv.CAP_PROP_FRAME_HEIGHT), "FPS: ", cap.get(cv.CAP_PROP_FPS))
|
||||
while True:
|
||||
# Reading input from the camera
|
||||
ret, frame = cap.read()
|
||||
if ret == False:
|
||||
print("Can't open camera/video stream")
|
||||
break
|
||||
# Taking input/position from the trackbar
|
||||
sigma = cv.getTrackbarPos("Kernel Size Bar", "Laplace of Image")
|
||||
# Setting kernel size
|
||||
ksize = (sigma*5)|1
|
||||
# Removing noise by blurring with a filter
|
||||
if smoothType == "GAUSSIAN":
|
||||
smoothed = cv.GaussianBlur(frame, (ksize, ksize), sigma, sigma)
|
||||
if smoothType == "BLUR":
|
||||
smoothed = cv.blur(frame, (ksize, ksize))
|
||||
if smoothType == "MedianBlur":
|
||||
smoothed = cv.medianBlur(frame, ksize)
|
||||
|
||||
# Apply Laplace function
|
||||
laplace = cv.Laplacian(smoothed, ddepth, 5)
|
||||
# Converting back to uint8
|
||||
result = cv.convertScaleAbs(laplace, (sigma+1)*0.25)
|
||||
# Display Output
|
||||
cv.imshow("Laplace of Image", result)
|
||||
k = cv.waitKey(30)
|
||||
if k == 27:
|
||||
return
|
||||
if __name__ == "__main__":
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Lucas-Kanade tracker
|
||||
====================
|
||||
|
||||
Lucas-Kanade sparse optical flow demo. Uses goodFeaturesToTrack
|
||||
for track initialization and back-tracking for match verification
|
||||
between frames.
|
||||
|
||||
Usage
|
||||
-----
|
||||
lk_track.py [<video_source>]
|
||||
|
||||
|
||||
Keys
|
||||
----
|
||||
ESC - exit
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import video
|
||||
from common import anorm2, draw_str
|
||||
|
||||
lk_params = dict( winSize = (15, 15),
|
||||
maxLevel = 2,
|
||||
criteria = (cv.TERM_CRITERIA_EPS | cv.TERM_CRITERIA_COUNT, 10, 0.03))
|
||||
|
||||
feature_params = dict( maxCorners = 500,
|
||||
qualityLevel = 0.3,
|
||||
minDistance = 7,
|
||||
blockSize = 7 )
|
||||
|
||||
class App:
|
||||
def __init__(self, video_src):
|
||||
self.track_len = 10
|
||||
self.detect_interval = 5
|
||||
self.tracks = []
|
||||
self.cam = video.create_capture(video_src)
|
||||
self.frame_idx = 0
|
||||
|
||||
def run(self):
|
||||
while True:
|
||||
_ret, frame = self.cam.read()
|
||||
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
|
||||
vis = frame.copy()
|
||||
|
||||
if len(self.tracks) > 0:
|
||||
img0, img1 = self.prev_gray, frame_gray
|
||||
p0 = np.float32([tr[-1] for tr in self.tracks]).reshape(-1, 1, 2)
|
||||
p1, _st, _err = cv.calcOpticalFlowPyrLK(img0, img1, p0, None, **lk_params)
|
||||
p0r, _st, _err = cv.calcOpticalFlowPyrLK(img1, img0, p1, None, **lk_params)
|
||||
d = abs(p0-p0r).reshape(-1, 2).max(-1)
|
||||
good = d < 1
|
||||
new_tracks = []
|
||||
for tr, (x, y), good_flag in zip(self.tracks, p1.reshape(-1, 2), good):
|
||||
if not good_flag:
|
||||
continue
|
||||
tr.append((x, y))
|
||||
if len(tr) > self.track_len:
|
||||
del tr[0]
|
||||
new_tracks.append(tr)
|
||||
cv.circle(vis, (int(x), int(y)), 2, (0, 255, 0), -1)
|
||||
self.tracks = new_tracks
|
||||
cv.polylines(vis, [np.int32(tr) for tr in self.tracks], False, (0, 255, 0))
|
||||
draw_str(vis, (20, 20), 'track count: %d' % len(self.tracks))
|
||||
|
||||
if self.frame_idx % self.detect_interval == 0:
|
||||
mask = np.zeros_like(frame_gray)
|
||||
mask[:] = 255
|
||||
for x, y in [np.int32(tr[-1]) for tr in self.tracks]:
|
||||
cv.circle(mask, (x, y), 5, 0, -1)
|
||||
p = cv.goodFeaturesToTrack(frame_gray, mask = mask, **feature_params)
|
||||
if p is not None:
|
||||
for x, y in np.float32(p).reshape(-1, 2):
|
||||
self.tracks.append([(x, y)])
|
||||
|
||||
|
||||
self.frame_idx += 1
|
||||
self.prev_gray = frame_gray
|
||||
cv.imshow('lk_track', vis)
|
||||
|
||||
ch = cv.waitKey(1)
|
||||
if ch == 27:
|
||||
break
|
||||
|
||||
def main():
|
||||
import sys
|
||||
try:
|
||||
video_src = sys.argv[1]
|
||||
except:
|
||||
video_src = 0
|
||||
|
||||
App(video_src).run()
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+56
@@ -0,0 +1,56 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
MSER detector demo
|
||||
==================
|
||||
|
||||
Usage:
|
||||
------
|
||||
mser.py [<video source>]
|
||||
|
||||
Keys:
|
||||
-----
|
||||
ESC - exit
|
||||
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import video
|
||||
import sys
|
||||
|
||||
def main():
|
||||
try:
|
||||
video_src = sys.argv[1]
|
||||
except:
|
||||
video_src = 0
|
||||
|
||||
cam = video.create_capture(video_src)
|
||||
mser = cv.MSER_create()
|
||||
|
||||
while True:
|
||||
ret, img = cam.read()
|
||||
if ret == 0:
|
||||
break
|
||||
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||
vis = img.copy()
|
||||
|
||||
regions, _ = mser.detectRegions(gray)
|
||||
hulls = [cv.convexHull(p.reshape(-1, 1, 2)) for p in regions]
|
||||
cv.polylines(vis, hulls, 1, (0, 255, 0))
|
||||
|
||||
cv.imshow('img', vis)
|
||||
if cv.waitKey(5) == 27:
|
||||
break
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+104
@@ -0,0 +1,104 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
example to show optical flow
|
||||
|
||||
USAGE: opt_flow.py [<video_source>]
|
||||
|
||||
Keys:
|
||||
1 - toggle HSV flow visualization
|
||||
2 - toggle glitch
|
||||
|
||||
Keys:
|
||||
ESC - exit
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import video
|
||||
|
||||
|
||||
def draw_flow(img, flow, step=16):
|
||||
h, w = img.shape[:2]
|
||||
y, x = np.mgrid[step/2:h:step, step/2:w:step].reshape(2,-1).astype(int)
|
||||
fx, fy = flow[y,x].T
|
||||
lines = np.vstack([x, y, x+fx, y+fy]).T.reshape(-1, 2, 2)
|
||||
lines = np.int32(lines + 0.5)
|
||||
vis = cv.cvtColor(img, cv.COLOR_GRAY2BGR)
|
||||
cv.polylines(vis, lines, 0, (0, 255, 0))
|
||||
for (x1, y1), (_x2, _y2) in lines:
|
||||
cv.circle(vis, (x1, y1), 1, (0, 255, 0), -1)
|
||||
return vis
|
||||
|
||||
|
||||
def draw_hsv(flow):
|
||||
h, w = flow.shape[:2]
|
||||
fx, fy = flow[:,:,0], flow[:,:,1]
|
||||
ang = np.arctan2(fy, fx) + np.pi
|
||||
v = np.sqrt(fx*fx+fy*fy)
|
||||
hsv = np.zeros((h, w, 3), np.uint8)
|
||||
hsv[...,0] = ang*(180/np.pi/2)
|
||||
hsv[...,1] = 255
|
||||
hsv[...,2] = np.minimum(v*4, 255)
|
||||
bgr = cv.cvtColor(hsv, cv.COLOR_HSV2BGR)
|
||||
return bgr
|
||||
|
||||
|
||||
def warp_flow(img, flow):
|
||||
h, w = flow.shape[:2]
|
||||
flow = -flow
|
||||
flow[:,:,0] += np.arange(w)
|
||||
flow[:,:,1] += np.arange(h)[:,np.newaxis]
|
||||
res = cv.remap(img, flow, None, cv.INTER_LINEAR)
|
||||
return res
|
||||
|
||||
def main():
|
||||
import sys
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except IndexError:
|
||||
fn = 0
|
||||
|
||||
cam = video.create_capture(fn)
|
||||
_ret, prev = cam.read()
|
||||
prevgray = cv.cvtColor(prev, cv.COLOR_BGR2GRAY)
|
||||
show_hsv = False
|
||||
show_glitch = False
|
||||
cur_glitch = prev.copy()
|
||||
|
||||
while True:
|
||||
_ret, img = cam.read()
|
||||
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||
flow = cv.calcOpticalFlowFarneback(prevgray, gray, None, 0.5, 3, 15, 3, 5, 1.2, 0)
|
||||
prevgray = gray
|
||||
|
||||
cv.imshow('flow', draw_flow(gray, flow))
|
||||
if show_hsv:
|
||||
cv.imshow('flow HSV', draw_hsv(flow))
|
||||
if show_glitch:
|
||||
cur_glitch = warp_flow(cur_glitch, flow)
|
||||
cv.imshow('glitch', cur_glitch)
|
||||
|
||||
ch = cv.waitKey(5)
|
||||
if ch == 27:
|
||||
break
|
||||
if ch == ord('1'):
|
||||
show_hsv = not show_hsv
|
||||
print('HSV flow visualization is', ['off', 'on'][show_hsv])
|
||||
if ch == ord('2'):
|
||||
show_glitch = not show_glitch
|
||||
if show_glitch:
|
||||
cur_glitch = img.copy()
|
||||
print('glitch is', ['off', 'on'][show_glitch])
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Simple "Square Detector" program.
|
||||
|
||||
Loads several images sequentially and tries to find squares in each image.
|
||||
'''
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
|
||||
def angle_cos(p0, p1, p2):
|
||||
d1, d2 = (p0-p1).astype('float'), (p2-p1).astype('float')
|
||||
return abs( np.dot(d1, d2) / np.sqrt( np.dot(d1, d1)*np.dot(d2, d2) ) )
|
||||
|
||||
def find_squares(img):
|
||||
img = cv.GaussianBlur(img, (5, 5), 0)
|
||||
squares = []
|
||||
for gray in cv.split(img):
|
||||
for thrs in range(0, 255, 26):
|
||||
if thrs == 0:
|
||||
bin = cv.Canny(gray, 0, 50, apertureSize=5)
|
||||
bin = cv.dilate(bin, None)
|
||||
else:
|
||||
_retval, bin = cv.threshold(gray, thrs, 255, cv.THRESH_BINARY)
|
||||
contours, _hierarchy = cv.findContours(bin, cv.RETR_LIST, cv.CHAIN_APPROX_SIMPLE)
|
||||
for cnt in contours:
|
||||
cnt_len = cv.arcLength(cnt, True)
|
||||
cnt = cv.approxPolyDP(cnt, 0.02*cnt_len, True)
|
||||
if len(cnt) == 4 and cv.contourArea(cnt) > 1000 and cv.isContourConvex(cnt):
|
||||
cnt = cnt.reshape(-1, 2)
|
||||
max_cos = np.max([angle_cos( cnt[i], cnt[(i+1) % 4], cnt[(i+2) % 4] ) for i in range(4)])
|
||||
if max_cos < 0.1:
|
||||
squares.append(cnt)
|
||||
return squares
|
||||
|
||||
def main():
|
||||
from glob import glob
|
||||
for fn in glob('../data/pic*.png'):
|
||||
img = cv.imread(fn)
|
||||
squares = find_squares(img)
|
||||
cv.drawContours( img, squares, -1, (0, 255, 0), 3 )
|
||||
cv.imshow('squares', img)
|
||||
ch = cv.waitKey()
|
||||
if ch == 27:
|
||||
break
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
@@ -0,0 +1,64 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Stitching sample
|
||||
================
|
||||
|
||||
Show how to use Stitcher API from python in a simple way to stitch panoramas
|
||||
or scans.
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
import argparse
|
||||
import sys
|
||||
|
||||
modes = (cv.Stitcher_PANORAMA, cv.Stitcher_SCANS)
|
||||
|
||||
parser = argparse.ArgumentParser(prog='stitching.py', description='Stitching sample.')
|
||||
parser.add_argument('--mode',
|
||||
type = int, choices = modes, default = cv.Stitcher_PANORAMA,
|
||||
help = 'Determines configuration of stitcher. The default is `PANORAMA` (%d), '
|
||||
'mode suitable for creating photo panoramas. Option `SCANS` (%d) is suitable '
|
||||
'for stitching materials under affine transformation, such as scans.' % modes)
|
||||
parser.add_argument('--output', default = 'result.jpg',
|
||||
help = 'Resulting image. The default is `result.jpg`.')
|
||||
parser.add_argument('img', nargs='+', help = 'input images')
|
||||
|
||||
__doc__ += '\n' + parser.format_help()
|
||||
|
||||
def main():
|
||||
args = parser.parse_args()
|
||||
|
||||
# read input images
|
||||
imgs = []
|
||||
for img_name in args.img:
|
||||
img = cv.imread(cv.samples.findFile(img_name))
|
||||
if img is None:
|
||||
print("can't read image " + img_name)
|
||||
sys.exit(-1)
|
||||
imgs.append(img)
|
||||
|
||||
#![stitching]
|
||||
stitcher = cv.Stitcher.create(args.mode)
|
||||
status, pano = stitcher.stitch(imgs)
|
||||
|
||||
if status != cv.Stitcher_OK:
|
||||
print("Can't stitch images, error code = %d" % status)
|
||||
sys.exit(-1)
|
||||
#![stitching]
|
||||
|
||||
cv.imwrite(args.output, pano)
|
||||
print("stitching completed successfully. %s saved!" % args.output)
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+55
@@ -0,0 +1,55 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Texture flow direction estimation.
|
||||
|
||||
Sample shows how cv.cornerEigenValsAndVecs function can be used
|
||||
to estimate image texture flow direction.
|
||||
|
||||
Usage:
|
||||
texture_flow.py [<image>]
|
||||
'''
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
|
||||
def main():
|
||||
import sys
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except:
|
||||
fn = 'starry_night.jpg'
|
||||
|
||||
img = cv.imread(cv.samples.findFile(fn))
|
||||
if img is None:
|
||||
print('Failed to load image file:', fn)
|
||||
sys.exit(1)
|
||||
|
||||
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
|
||||
h, w = img.shape[:2]
|
||||
|
||||
eigen = cv.cornerEigenValsAndVecs(gray, 15, 3)
|
||||
eigen = eigen.reshape(h, w, 3, 2) # [[e1, e2], v1, v2]
|
||||
flow = eigen[:,:,2]
|
||||
|
||||
vis = img.copy()
|
||||
vis[:] = (192 + np.uint32(vis)) / 2
|
||||
d = 12
|
||||
points = np.dstack( np.mgrid[d/2:w:d, d/2:h:d] ).reshape(-1, 2)
|
||||
for x, y in np.int32(points):
|
||||
vx, vy = np.int32(flow[y, x]*d)
|
||||
cv.line(vis, (x-vx, y-vy), (x+vx, y+vy), (0, 0, 0), 1, cv.LINE_AA)
|
||||
cv.imshow('input', img)
|
||||
cv.imshow('flow', vis)
|
||||
cv.waitKey()
|
||||
|
||||
print('Done')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
main()
|
||||
cv.destroyAllWindows()
|
||||
Executable
+85
@@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
'''
|
||||
Watershed segmentation
|
||||
=========
|
||||
|
||||
This program demonstrates the watershed segmentation algorithm
|
||||
in OpenCV: watershed().
|
||||
|
||||
Usage
|
||||
-----
|
||||
watershed.py [image filename]
|
||||
|
||||
Keys
|
||||
----
|
||||
1-7 - switch marker color
|
||||
SPACE - update segmentation
|
||||
r - reset
|
||||
a - toggle autoupdate
|
||||
ESC - exit
|
||||
|
||||
'''
|
||||
|
||||
|
||||
# Python 2/3 compatibility
|
||||
from __future__ import print_function
|
||||
|
||||
import numpy as np
|
||||
import cv2 as cv
|
||||
from common import Sketcher
|
||||
|
||||
class App:
|
||||
def __init__(self, fn):
|
||||
self.img = cv.imread(fn)
|
||||
if self.img is None:
|
||||
raise Exception('Failed to load image file: %s' % fn)
|
||||
|
||||
h, w = self.img.shape[:2]
|
||||
self.markers = np.zeros((h, w), np.int32)
|
||||
self.markers_vis = self.img.copy()
|
||||
self.cur_marker = 1
|
||||
self.colors = np.int32( list(np.ndindex(2, 2, 2)) ) * 255
|
||||
|
||||
self.auto_update = True
|
||||
self.sketch = Sketcher('img', [self.markers_vis, self.markers], self.get_colors)
|
||||
|
||||
def get_colors(self):
|
||||
return list(map(int, self.colors[self.cur_marker])), self.cur_marker
|
||||
|
||||
def watershed(self):
|
||||
m = self.markers.copy()
|
||||
cv.watershed(self.img, m)
|
||||
overlay = self.colors[np.maximum(m, 0)]
|
||||
vis = cv.addWeighted(self.img, 0.5, overlay, 0.5, 0.0, dtype=cv.CV_8UC3)
|
||||
cv.imshow('watershed', vis)
|
||||
|
||||
def run(self):
|
||||
while cv.getWindowProperty('img', 0) != -1 or cv.getWindowProperty('watershed', 0) != -1:
|
||||
ch = cv.waitKey(50)
|
||||
if ch == 27:
|
||||
break
|
||||
if ch >= ord('1') and ch <= ord('7'):
|
||||
self.cur_marker = ch - ord('0')
|
||||
print('marker: ', self.cur_marker)
|
||||
if ch == ord(' ') or (self.sketch.dirty and self.auto_update):
|
||||
self.watershed()
|
||||
self.sketch.dirty = False
|
||||
if ch in [ord('a'), ord('A')]:
|
||||
self.auto_update = not self.auto_update
|
||||
print('auto_update if', ['off', 'on'][self.auto_update])
|
||||
if ch in [ord('r'), ord('R')]:
|
||||
self.markers[:] = 0
|
||||
self.markers_vis[:] = self.img
|
||||
self.sketch.show()
|
||||
cv.destroyAllWindows()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
print(__doc__)
|
||||
import sys
|
||||
try:
|
||||
fn = sys.argv[1]
|
||||
except:
|
||||
fn = 'fruits.jpg'
|
||||
App(cv.samples.findFile(fn)).run()
|
||||
Reference in New Issue
Block a user