mirror of
https://github.com/opencv/opencv.git
synced 2026-07-30 07:43:03 +04:00
"atomic bomb" commit. Reorganized OpenCV directory structure
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
# -------------------------------------------------------------------------
|
||||
# CMake file for Python samples. See root CMakeLists.txt
|
||||
# -------------------------------------------------------------------------
|
||||
|
||||
file(GLOB PYTHON_SAMPLES *.py)
|
||||
if(NOT WIN32)
|
||||
install(FILES ${PYTHON_SAMPLES}
|
||||
DESTINATION share/opencv/samples/python
|
||||
PERMISSIONS OWNER_READ OWNER_EXECUTE
|
||||
GROUP_READ GROUP_EXECUTE
|
||||
WORLD_READ WORLD_EXECUTE)
|
||||
endif()
|
||||
|
||||
Executable
+193
@@ -0,0 +1,193 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
#############################################################################
|
||||
# definition of some constants
|
||||
|
||||
# how many bins we want for the histogram, and their ranges
|
||||
hdims = 16
|
||||
hranges = [[0, 180]]
|
||||
|
||||
# ranges for the limitation of the histogram
|
||||
vmin = 10
|
||||
vmax = 256
|
||||
smin = 30
|
||||
|
||||
# the range we want to monitor
|
||||
hsv_min = cv.cvScalar (0, smin, vmin, 0)
|
||||
hsv_max = cv.cvScalar (180, 256, vmax, 0)
|
||||
|
||||
#############################################################################
|
||||
# some useful functions
|
||||
|
||||
def hsv2rgb (hue):
|
||||
# convert the hue value to the corresponding rgb value
|
||||
|
||||
sector_data = [[0, 2, 1],
|
||||
[1, 2, 0],
|
||||
[1, 0, 2],
|
||||
[2, 0, 1],
|
||||
[2, 1, 0],
|
||||
[0, 1, 2]]
|
||||
hue *= 0.1 / 3
|
||||
sector = cv.cvFloor (hue)
|
||||
p = cv.cvRound (255 * (hue - sector))
|
||||
if sector & 1:
|
||||
p ^= 255
|
||||
|
||||
rgb = {}
|
||||
rgb [sector_data [sector][0]] = 255
|
||||
rgb [sector_data [sector][1]] = 0
|
||||
rgb [sector_data [sector][2]] = p
|
||||
|
||||
return cv.cvScalar (rgb [2], rgb [1], rgb [0], 0)
|
||||
|
||||
#############################################################################
|
||||
# so, here is the main part of the program
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# a small welcome
|
||||
print "OpenCV Python wrapper test"
|
||||
print "OpenCV version: %s (%d, %d, %d)" % (cv.CV_VERSION,
|
||||
cv.CV_MAJOR_VERSION,
|
||||
cv.CV_MINOR_VERSION,
|
||||
cv.CV_SUBMINOR_VERSION)
|
||||
|
||||
# first, create the necessary windows
|
||||
highgui.cvNamedWindow ('Camera', highgui.CV_WINDOW_AUTOSIZE)
|
||||
highgui.cvNamedWindow ('Histogram', highgui.CV_WINDOW_AUTOSIZE)
|
||||
|
||||
# move the new window to a better place
|
||||
highgui.cvMoveWindow ('Camera', 10, 40)
|
||||
highgui.cvMoveWindow ('Histogram', 10, 270)
|
||||
|
||||
try:
|
||||
# try to get the device number from the command line
|
||||
device = int (sys.argv [1])
|
||||
|
||||
# got it ! so remove it from the arguments
|
||||
del sys.argv [1]
|
||||
except (IndexError, ValueError):
|
||||
# no device number on the command line, assume we want the 1st device
|
||||
device = 0
|
||||
|
||||
if len (sys.argv) == 1:
|
||||
# no argument on the command line, try to use the camera
|
||||
capture = highgui.cvCreateCameraCapture (device)
|
||||
|
||||
# set the wanted image size from the camera
|
||||
highgui.cvSetCaptureProperty (capture,
|
||||
highgui.CV_CAP_PROP_FRAME_WIDTH, 320)
|
||||
highgui.cvSetCaptureProperty (capture,
|
||||
highgui.CV_CAP_PROP_FRAME_HEIGHT, 240)
|
||||
else:
|
||||
# we have an argument on the command line,
|
||||
# we can assume this is a file name, so open it
|
||||
capture = highgui.cvCreateFileCapture (sys.argv [1])
|
||||
|
||||
# check that capture device is OK
|
||||
if not capture:
|
||||
print "Error opening capture device"
|
||||
sys.exit (1)
|
||||
|
||||
# create an image to put in the histogram
|
||||
histimg = cv.cvCreateImage (cv.cvSize (320,240), 8, 3)
|
||||
|
||||
# init the image of the histogram to black
|
||||
cv.cvSetZero (histimg)
|
||||
|
||||
# capture the 1st frame to get some propertie on it
|
||||
frame = highgui.cvQueryFrame (capture)
|
||||
|
||||
# get some properties of the frame
|
||||
frame_size = cv.cvGetSize (frame)
|
||||
|
||||
# compute which selection of the frame we want to monitor
|
||||
selection = cv.cvRect (0, 0, frame.width, frame.height)
|
||||
|
||||
# create some images usefull later
|
||||
hue = cv.cvCreateImage (frame_size, 8, 1)
|
||||
mask = cv.cvCreateImage (frame_size, 8, 1)
|
||||
hsv = cv.cvCreateImage (frame_size, 8, 3 )
|
||||
|
||||
# create the histogram
|
||||
hist = cv.cvCreateHist ([hdims], cv.CV_HIST_ARRAY, hranges, 1)
|
||||
|
||||
while 1:
|
||||
# do forever
|
||||
|
||||
# 1. capture the current image
|
||||
frame = highgui.cvQueryFrame (capture)
|
||||
if frame is None:
|
||||
# no image captured... end the processing
|
||||
break
|
||||
|
||||
# mirror the captured image
|
||||
cv.cvFlip (frame, None, 1)
|
||||
|
||||
# compute the hsv version of the image
|
||||
cv.cvCvtColor (frame, hsv, cv.CV_BGR2HSV)
|
||||
|
||||
# compute which pixels are in the wanted range
|
||||
cv.cvInRangeS (hsv, hsv_min, hsv_max, mask)
|
||||
|
||||
# extract the hue from the hsv array
|
||||
cv.cvSplit (hsv, hue, None, None, None)
|
||||
|
||||
# select the rectangle of interest in the hue/mask arrays
|
||||
hue_roi = cv.cvGetSubRect (hue, selection)
|
||||
mask_roi = cv.cvGetSubRect (mask, selection)
|
||||
|
||||
# it's time to compute the histogram
|
||||
cv.cvCalcHist (hue_roi, hist, 0, mask_roi)
|
||||
|
||||
# extract the min and max value of the histogram
|
||||
min_val, max_val, min_idx, max_idx = cv.cvGetMinMaxHistValue (hist)
|
||||
|
||||
# compute the scale factor
|
||||
if max_val > 0:
|
||||
scale = 255. / max_val
|
||||
else:
|
||||
scale = 0.
|
||||
|
||||
# scale the histograms
|
||||
cv.cvConvertScale (hist.bins, hist.bins, scale, 0)
|
||||
|
||||
# clear the histogram image
|
||||
cv.cvSetZero (histimg)
|
||||
|
||||
# compute the width for each bin do display
|
||||
bin_w = histimg.width / hdims
|
||||
|
||||
for i in range (hdims):
|
||||
# for all the bins
|
||||
|
||||
# get the value, and scale to the size of the hist image
|
||||
val = cv.cvRound (cv.cvGetReal1D (hist.bins, i)
|
||||
* histimg.height / 255)
|
||||
|
||||
# compute the color
|
||||
color = hsv2rgb (i * 180. / hdims)
|
||||
|
||||
# draw the rectangle in the wanted color
|
||||
cv.cvRectangle (histimg,
|
||||
cv.cvPoint (i * bin_w, histimg.height),
|
||||
cv.cvPoint ((i + 1) * bin_w, histimg.height - val),
|
||||
color, -1, 8, 0)
|
||||
|
||||
# we can now display the images
|
||||
highgui.cvShowImage ('Camera', frame)
|
||||
highgui.cvShowImage ('Histogram', histimg)
|
||||
|
||||
# handle events
|
||||
k = highgui.cvWaitKey (10)
|
||||
|
||||
if k == '\x1b':
|
||||
# user has press the ESC key, so exit
|
||||
break
|
||||
Executable
+106
@@ -0,0 +1,106 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import sys
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
# the codec existing in cvcapp.cpp,
|
||||
# need to have a better way to specify them in the future
|
||||
# WARNING: I have see only MPEG1VIDEO working on my computer
|
||||
H263 = 0x33363255
|
||||
H263I = 0x33363249
|
||||
MSMPEG4V3 = 0x33564944
|
||||
MPEG4 = 0x58564944
|
||||
MSMPEG4V2 = 0x3234504D
|
||||
MJPEG = 0x47504A4D
|
||||
MPEG1VIDEO = 0x314D4950
|
||||
AC3 = 0x2000
|
||||
MP2 = 0x50
|
||||
FLV1 = 0x31564C46
|
||||
|
||||
#############################################################################
|
||||
# so, here is the main part of the program
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# a small welcome
|
||||
print "OpenCV Python capture video"
|
||||
|
||||
# first, create the necessary window
|
||||
highgui.cvNamedWindow ('Camera', highgui.CV_WINDOW_AUTOSIZE)
|
||||
|
||||
# move the new window to a better place
|
||||
highgui.cvMoveWindow ('Camera', 10, 10)
|
||||
|
||||
try:
|
||||
# try to get the device number from the command line
|
||||
device = int (sys.argv [1])
|
||||
|
||||
# got it ! so remove it from the arguments
|
||||
del sys.argv [1]
|
||||
except (IndexError, ValueError):
|
||||
# no device number on the command line, assume we want the 1st device
|
||||
device = 0
|
||||
|
||||
if len (sys.argv) == 1:
|
||||
# no argument on the command line, try to use the camera
|
||||
capture = highgui.cvCreateCameraCapture (device)
|
||||
else:
|
||||
# we have an argument on the command line,
|
||||
# we can assume this is a file name, so open it
|
||||
capture = highgui.cvCreateFileCapture (sys.argv [1])
|
||||
|
||||
# check that capture device is OK
|
||||
if not capture:
|
||||
print "Error opening capture device"
|
||||
sys.exit (1)
|
||||
|
||||
# capture the 1st frame to get some propertie on it
|
||||
frame = highgui.cvQueryFrame (capture)
|
||||
|
||||
# get size of the frame
|
||||
frame_size = cv.cvGetSize (frame)
|
||||
|
||||
# get the frame rate of the capture device
|
||||
fps = highgui.cvGetCaptureProperty (capture, highgui.CV_CAP_PROP_FPS)
|
||||
if fps == 0:
|
||||
# no fps getted, so set it to 30 by default
|
||||
fps = 30
|
||||
|
||||
# create the writer
|
||||
writer = highgui.cvCreateVideoWriter ("captured.mpg", MPEG1VIDEO,
|
||||
fps, frame_size, True)
|
||||
|
||||
# check the writer is OK
|
||||
if not writer:
|
||||
print "Error opening writer"
|
||||
sys.exit (1)
|
||||
|
||||
while 1:
|
||||
# do forever
|
||||
|
||||
# 1. capture the current image
|
||||
frame = highgui.cvQueryFrame (capture)
|
||||
if frame is None:
|
||||
# no image captured... end the processing
|
||||
break
|
||||
|
||||
# write the frame to the output file
|
||||
highgui.cvWriteFrame (writer, frame)
|
||||
|
||||
# display the frames to have a visual output
|
||||
highgui.cvShowImage ('Camera', frame)
|
||||
|
||||
# handle events
|
||||
k = highgui.cvWaitKey (5)
|
||||
|
||||
if k % 0x100 == 27:
|
||||
# user has press the ESC key, so exit
|
||||
break
|
||||
|
||||
# end working with the writer
|
||||
# not working at this time... Need to implement some typemaps...
|
||||
# but exiting without calling it is OK in this simple application
|
||||
#highgui.cvReleaseVideoWriter (writer)
|
||||
Executable
+18
@@ -0,0 +1,18 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
cvNamedWindow("win")
|
||||
filename = sys.argv[1]
|
||||
im = cvLoadImage(filename, CV_LOAD_IMAGE_GRAYSCALE)
|
||||
im3 = cvLoadImage(filename, CV_LOAD_IMAGE_COLOR)
|
||||
chessboard_dim = cvSize( 5, 6 )
|
||||
|
||||
found_all, corners = cvFindChessboardCorners( im, chessboard_dim )
|
||||
|
||||
cvDrawChessboardCorners( im3, chessboard_dim, corners, found_all )
|
||||
|
||||
cvShowImage("win", im3);
|
||||
cvWaitKey()
|
||||
Executable
+137
@@ -0,0 +1,137 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
print "OpenCV Python version of contours"
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
# some default constants
|
||||
_SIZE = 500
|
||||
_DEFAULT_LEVEL = 3
|
||||
|
||||
# definition of some colors
|
||||
_red = cv.cvScalar (0, 0, 255, 0);
|
||||
_green = cv.cvScalar (0, 255, 0, 0);
|
||||
_white = cv.cvRealScalar (255)
|
||||
_black = cv.cvRealScalar (0)
|
||||
|
||||
# the callback on the trackbar, to set the level of contours we want
|
||||
# to display
|
||||
def on_trackbar (position):
|
||||
|
||||
# create the image for putting in it the founded contours
|
||||
contours_image = cv.cvCreateImage (cv.cvSize (_SIZE, _SIZE), 8, 3)
|
||||
|
||||
# compute the real level of display, given the current position
|
||||
levels = position - 3
|
||||
|
||||
# initialisation
|
||||
_contours = contours
|
||||
|
||||
if levels <= 0:
|
||||
# zero or negative value
|
||||
# => get to the nearest face to make it look more funny
|
||||
_contours = contours.h_next.h_next.h_next
|
||||
|
||||
# first, clear the image where we will draw contours
|
||||
cv.cvSetZero (contours_image)
|
||||
|
||||
# draw contours in red and green
|
||||
cv.cvDrawContours (contours_image, _contours,
|
||||
_red, _green,
|
||||
levels, 3, cv.CV_AA,
|
||||
cv.cvPoint (0, 0))
|
||||
|
||||
# finally, show the image
|
||||
highgui.cvShowImage ("contours", contours_image)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# create the image where we want to display results
|
||||
image = cv.cvCreateImage (cv.cvSize (_SIZE, _SIZE), 8, 1)
|
||||
|
||||
# start with an empty image
|
||||
cv.cvSetZero (image)
|
||||
|
||||
# draw the original picture
|
||||
for i in range (6):
|
||||
dx = (i % 2) * 250 - 30
|
||||
dy = (i / 2) * 150
|
||||
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 150, dy + 100),
|
||||
cv.cvSize (100, 70),
|
||||
0, 0, 360, _white, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 115, dy + 70),
|
||||
cv.cvSize (30, 20),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 185, dy + 70),
|
||||
cv.cvSize (30, 20),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 115, dy + 70),
|
||||
cv.cvSize (15, 15),
|
||||
0, 0, 360, _white, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 185, dy + 70),
|
||||
cv.cvSize (15, 15),
|
||||
0, 0, 360, _white, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 115, dy + 70),
|
||||
cv.cvSize (5, 5),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 185, dy + 70),
|
||||
cv.cvSize (5, 5),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 150, dy + 100),
|
||||
cv.cvSize (10, 5),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 150, dy + 150),
|
||||
cv.cvSize (40, 10),
|
||||
0, 0, 360, _black, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 27, dy + 100),
|
||||
cv.cvSize (20, 35),
|
||||
0, 0, 360, _white, -1, 8, 0)
|
||||
cv.cvEllipse (image,
|
||||
cv.cvPoint (dx + 273, dy + 100),
|
||||
cv.cvSize (20, 35),
|
||||
0, 0, 360, _white, -1, 8, 0)
|
||||
|
||||
# create window and display the original picture in it
|
||||
highgui.cvNamedWindow ("image", 1)
|
||||
highgui.cvShowImage ("image", image)
|
||||
|
||||
# create the storage area
|
||||
storage = cv.cvCreateMemStorage (0)
|
||||
|
||||
# find the contours
|
||||
nb_contours, contours = cv.cvFindContours (image,
|
||||
storage,
|
||||
cv.sizeof_CvContour,
|
||||
cv.CV_RETR_TREE,
|
||||
cv.CV_CHAIN_APPROX_SIMPLE,
|
||||
cv.cvPoint (0,0))
|
||||
|
||||
# comment this out if you do not want approximation
|
||||
contours = cv.cvApproxPoly (contours, cv.sizeof_CvContour,
|
||||
storage,
|
||||
cv.CV_POLY_APPROX_DP, 3, 1)
|
||||
|
||||
# create the window for the contours
|
||||
highgui.cvNamedWindow ("contours", 1)
|
||||
|
||||
# create the trackbar, to enable the change of the displayed level
|
||||
highgui.cvCreateTrackbar ("levels+3", "contours", 3, 7, on_trackbar)
|
||||
|
||||
# call one time the callback, so we will have the 1st display done
|
||||
on_trackbar (_DEFAULT_LEVEL)
|
||||
|
||||
# wait a key pressed to end
|
||||
highgui.cvWaitKey (0)
|
||||
Executable
+78
@@ -0,0 +1,78 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
print "OpenCV Python version of convexhull"
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
# to generate random values
|
||||
import random
|
||||
|
||||
# how many points we want at max
|
||||
_MAX_POINTS = 100
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# main object to get random values from
|
||||
my_random = random.Random ()
|
||||
|
||||
# create the image where we want to display results
|
||||
image = cv.cvCreateImage (cv.cvSize (500, 500), 8, 3)
|
||||
|
||||
# create the window to put the image in
|
||||
highgui.cvNamedWindow ('hull', highgui.CV_WINDOW_AUTOSIZE)
|
||||
|
||||
while True:
|
||||
# do forever
|
||||
|
||||
# get a random number of points
|
||||
count = my_random.randrange (0, _MAX_POINTS) + 1
|
||||
|
||||
# initialisations
|
||||
points = []
|
||||
|
||||
for i in range (count):
|
||||
# generate a random point
|
||||
points.append (cv.cvPoint (
|
||||
my_random.randrange (0, image.width / 2) + image.width / 4,
|
||||
my_random.randrange (0, image.width / 2) + image.width / 4
|
||||
))
|
||||
|
||||
# compute the convex hull
|
||||
hull = cv.cvConvexHull2 (points, cv.CV_CLOCKWISE, 0)
|
||||
|
||||
# start with an empty image
|
||||
cv.cvSetZero (image)
|
||||
|
||||
for i in range (count):
|
||||
# draw all the points
|
||||
cv.cvCircle (image, points [i], 2,
|
||||
cv.cvScalar (0, 0, 255, 0),
|
||||
cv.CV_FILLED, cv.CV_AA, 0)
|
||||
|
||||
# start the line from the last point
|
||||
pt0 = points [hull [-1]]
|
||||
|
||||
for point_index in hull:
|
||||
# connect the previous point to the current one
|
||||
|
||||
# get the current one
|
||||
pt1 = points [point_index]
|
||||
|
||||
# draw
|
||||
cv.cvLine (image, pt0, pt1,
|
||||
cv.cvScalar (0, 255, 0, 0),
|
||||
1, cv.CV_AA, 0)
|
||||
|
||||
# now, current one will be the previous one for the next iteration
|
||||
pt0 = pt1
|
||||
|
||||
# display the final image
|
||||
highgui.cvShowImage ('hull', image)
|
||||
|
||||
# handle events, and wait a key pressed
|
||||
k = highgui.cvWaitKey (0)
|
||||
if k == '\x1b':
|
||||
# user has press the ESC key, so exit
|
||||
break
|
||||
Executable
+149
@@ -0,0 +1,149 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
the script demostrates iterative construction of
|
||||
delaunay triangulation and voronoi tesselation
|
||||
|
||||
Original Author (C version): ?
|
||||
Converted to Python by: Roman Stanchak
|
||||
"""
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
from random import random,randint
|
||||
|
||||
def draw_subdiv_point( img, fp, color ):
|
||||
cvCircle( img, cvPoint(cvRound(fp.x), cvRound(fp.y)), 3, color, CV_FILLED, 8, 0 );
|
||||
|
||||
|
||||
|
||||
def draw_subdiv_edge( img, edge, color ):
|
||||
org_pt = cvSubdiv2DEdgeOrg(edge);
|
||||
dst_pt = cvSubdiv2DEdgeDst(edge);
|
||||
|
||||
if org_pt and dst_pt :
|
||||
|
||||
org = org_pt.pt;
|
||||
dst = dst_pt.pt;
|
||||
|
||||
iorg = cvPoint( cvRound( org.x ), cvRound( org.y ));
|
||||
idst = cvPoint( cvRound( dst.x ), cvRound( dst.y ));
|
||||
|
||||
cvLine( img, iorg, idst, color, 1, CV_AA, 0 );
|
||||
|
||||
|
||||
def draw_subdiv( img, subdiv, delaunay_color, voronoi_color ):
|
||||
|
||||
total = subdiv.edges.total;
|
||||
elem_size = subdiv.edges.elem_size;
|
||||
|
||||
for edge in subdiv.edges:
|
||||
edge_rot = cvSubdiv2DRotateEdge( edge, 1 )
|
||||
|
||||
if( CV_IS_SET_ELEM( edge )):
|
||||
draw_subdiv_edge( img, edge_rot, voronoi_color );
|
||||
draw_subdiv_edge( img, edge, delaunay_color );
|
||||
|
||||
|
||||
def locate_point( subdiv, fp, img, active_color ):
|
||||
|
||||
[res, e0, p] = cvSubdiv2DLocate( subdiv, fp );
|
||||
|
||||
if e0:
|
||||
e = e0
|
||||
while True:
|
||||
draw_subdiv_edge( img, e, active_color );
|
||||
e = cvSubdiv2DGetEdge(e,CV_NEXT_AROUND_LEFT);
|
||||
if e == e0:
|
||||
break
|
||||
|
||||
draw_subdiv_point( img, fp, active_color );
|
||||
|
||||
|
||||
def draw_subdiv_facet( img, edge ):
|
||||
|
||||
t = edge;
|
||||
count = 0;
|
||||
|
||||
# count number of edges in facet
|
||||
while count == 0 or t != edge:
|
||||
count+=1
|
||||
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
|
||||
|
||||
buf = []
|
||||
|
||||
# gather points
|
||||
t = edge;
|
||||
for i in range(count):
|
||||
assert t>4
|
||||
pt = cvSubdiv2DEdgeOrg( t );
|
||||
if not pt:
|
||||
break;
|
||||
buf.append( cvPoint( cvRound(pt.pt.x), cvRound(pt.pt.y) ) );
|
||||
t = cvSubdiv2DGetEdge( t, CV_NEXT_AROUND_LEFT );
|
||||
|
||||
if( len(buf)==count ):
|
||||
pt = cvSubdiv2DEdgeDst( cvSubdiv2DRotateEdge( edge, 1 ));
|
||||
cvFillConvexPoly( img, buf, CV_RGB(randint(0,255),randint(0,255),randint(0,255)), CV_AA, 0 );
|
||||
cvPolyLine( img, [buf], 1, CV_RGB(0,0,0), 1, CV_AA, 0);
|
||||
draw_subdiv_point( img, pt.pt, CV_RGB(0,0,0));
|
||||
|
||||
def paint_voronoi( subdiv, img ):
|
||||
total = subdiv.edges.total;
|
||||
elem_size = subdiv.edges.elem_size;
|
||||
|
||||
cvCalcSubdivVoronoi2D( subdiv );
|
||||
|
||||
for edge in subdiv.edges:
|
||||
|
||||
if( CV_IS_SET_ELEM( edge )):
|
||||
# left
|
||||
draw_subdiv_facet( img, cvSubdiv2DRotateEdge( edge, 1 ));
|
||||
|
||||
# right
|
||||
draw_subdiv_facet( img, cvSubdiv2DRotateEdge( edge, 3 ));
|
||||
|
||||
if __name__ == '__main__':
|
||||
win = "source";
|
||||
rect = cvRect( 0, 0, 600, 600 );
|
||||
|
||||
active_facet_color = CV_RGB( 255, 0, 0 );
|
||||
delaunay_color = CV_RGB( 0,0,0);
|
||||
voronoi_color = CV_RGB(0, 180, 0);
|
||||
bkgnd_color = CV_RGB(255,255,255);
|
||||
|
||||
img = cvCreateImage( cvSize(rect.width,rect.height), 8, 3 );
|
||||
cvSet( img, bkgnd_color );
|
||||
|
||||
cvNamedWindow( win, 1 );
|
||||
|
||||
storage = cvCreateMemStorage(0);
|
||||
subdiv = cvCreateSubdivDelaunay2D( rect, storage );
|
||||
|
||||
print "Delaunay triangulation will be build now interactively."
|
||||
print "To stop the process, press any key\n";
|
||||
|
||||
for i in range(200):
|
||||
fp = cvPoint2D32f( random()*(rect.width-10)+5, random()*(rect.height-10)+5 )
|
||||
|
||||
locate_point( subdiv, fp, img, active_facet_color );
|
||||
cvShowImage( win, img );
|
||||
|
||||
if( cvWaitKey( 100 ) >= 0 ):
|
||||
break;
|
||||
|
||||
cvSubdivDelaunay2DInsert( subdiv, fp );
|
||||
cvCalcSubdivVoronoi2D( subdiv );
|
||||
cvSet( img, bkgnd_color );
|
||||
draw_subdiv( img, subdiv, delaunay_color, voronoi_color );
|
||||
cvShowImage( win, img );
|
||||
|
||||
if( cvWaitKey( 100 ) >= 0 ):
|
||||
break;
|
||||
|
||||
|
||||
cvSet( img, bkgnd_color );
|
||||
paint_voronoi( subdiv, img );
|
||||
cvShowImage( win, img );
|
||||
|
||||
cvWaitKey(0);
|
||||
|
||||
cvDestroyWindow( win );
|
||||
Executable
+102
@@ -0,0 +1,102 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
file_name = "../c/baboon.jpg";
|
||||
|
||||
_brightness = 100
|
||||
_contrast = 100
|
||||
Gbrightness = 100
|
||||
Gcontrast = 100
|
||||
|
||||
hist_size = 64
|
||||
range_0=[0,256]
|
||||
ranges = [ range_0 ]
|
||||
src_image=None
|
||||
dst_image=None
|
||||
hist_image=None
|
||||
hist=None
|
||||
lut=cvCreateMat(256,1,CV_8U)
|
||||
|
||||
# brightness/contrast callback function
|
||||
def update_brightness( val ):
|
||||
global Gbrightness # global tag is required, or we get UnboundLocalError
|
||||
Gbrightness = val
|
||||
update_brightcont( )
|
||||
|
||||
def update_contrast( val ):
|
||||
global Gcontrast # global tag is required, or we get UnboundLocalError
|
||||
Gcontrast = val
|
||||
update_brightcont( )
|
||||
|
||||
def update_brightcont():
|
||||
# no global tag required for images ???
|
||||
|
||||
brightness = Gbrightness - 100;
|
||||
contrast = Gcontrast - 100;
|
||||
max_value = 0;
|
||||
|
||||
# The algorithm is by Werner D. Streidt
|
||||
# (http://visca.com/ffactory/archives/5-99/msg00021.html)
|
||||
if( contrast > 0 ):
|
||||
delta = 127.*contrast/100;
|
||||
a = 255./(255. - delta*2);
|
||||
b = a*(brightness - delta);
|
||||
else:
|
||||
delta = -128.*contrast/100;
|
||||
a = (256.-delta*2)/255.;
|
||||
b = a*brightness + delta;
|
||||
|
||||
for i in range(256):
|
||||
v = cvRound(a*i + b);
|
||||
if( v < 0 ):
|
||||
v = 0;
|
||||
if( v > 255 ):
|
||||
v = 255;
|
||||
lut[i] = v;
|
||||
|
||||
cvLUT( src_image, dst_image, lut );
|
||||
cvShowImage( "image", dst_image );
|
||||
|
||||
cvCalcHist( dst_image, hist, 0, None );
|
||||
cvZero( dst_image );
|
||||
min_value, max_value = cvGetMinMaxHistValue( hist );
|
||||
cvScale( hist.bins, hist.bins, float(hist_image.height)/max_value, 0 );
|
||||
#cvNormalizeHist( hist, 1000 );
|
||||
|
||||
cvSet( hist_image, cvScalarAll(255));
|
||||
bin_w = cvRound(float(hist_image.width)/hist_size);
|
||||
|
||||
for i in range(hist_size):
|
||||
cvRectangle( hist_image, cvPoint(i*bin_w, hist_image.height),
|
||||
cvPoint((i+1)*bin_w, hist_image.height - cvRound(cvGetReal1D(hist.bins,i))),
|
||||
cvScalarAll(0), -1, 8, 0 );
|
||||
|
||||
cvShowImage( "histogram", hist_image );
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
# Load the source image. HighGUI use.
|
||||
if len(sys.argv)>1:
|
||||
file_name = sys.argv[1]
|
||||
|
||||
src_image = cvLoadImage( file_name, 0 );
|
||||
|
||||
if not src_image:
|
||||
print "Image was not loaded.";
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
dst_image = cvCloneImage(src_image);
|
||||
hist_image = cvCreateImage(cvSize(320,200), 8, 1);
|
||||
hist = cvCreateHist([hist_size], CV_HIST_ARRAY, ranges, 1);
|
||||
|
||||
cvNamedWindow("image", 0);
|
||||
cvNamedWindow("histogram", 0);
|
||||
|
||||
cvCreateTrackbar("brightness", "image", _brightness, 200, update_brightness);
|
||||
cvCreateTrackbar("contrast", "image", _contrast, 200, update_contrast);
|
||||
|
||||
update_brightcont();
|
||||
cvWaitKey(0);
|
||||
Executable
+107
@@ -0,0 +1,107 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
# Rearrange the quadrants of Fourier image so that the origin is at
|
||||
# the image center
|
||||
# src & dst arrays of equal size & type
|
||||
def cvShiftDFT(src_arr, dst_arr ):
|
||||
|
||||
size = cvGetSize(src_arr)
|
||||
dst_size = cvGetSize(dst_arr)
|
||||
|
||||
if(dst_size.width != size.width or
|
||||
dst_size.height != size.height) :
|
||||
cvError( CV_StsUnmatchedSizes, "cvShiftDFT", "Source and Destination arrays must have equal sizes", __FILE__, __LINE__ )
|
||||
|
||||
if(src_arr is dst_arr):
|
||||
tmp = cvCreateMat(size.height/2, size.width/2, cvGetElemType(src_arr))
|
||||
|
||||
cx = size.width/2
|
||||
cy = size.height/2 # image center
|
||||
|
||||
q1 = cvGetSubRect( src_arr, cvRect(0,0,cx, cy) )
|
||||
q2 = cvGetSubRect( src_arr, cvRect(cx,0,cx,cy) )
|
||||
q3 = cvGetSubRect( src_arr, cvRect(cx,cy,cx,cy) )
|
||||
q4 = cvGetSubRect( src_arr, cvRect(0,cy,cx,cy) )
|
||||
d1 = cvGetSubRect( src_arr, cvRect(0,0,cx,cy) )
|
||||
d2 = cvGetSubRect( src_arr, cvRect(cx,0,cx,cy) )
|
||||
d3 = cvGetSubRect( src_arr, cvRect(cx,cy,cx,cy) )
|
||||
d4 = cvGetSubRect( src_arr, cvRect(0,cy,cx,cy) )
|
||||
|
||||
if(src_arr is not dst_arr):
|
||||
if( not CV_ARE_TYPES_EQ( q1, d1 )):
|
||||
cvError( CV_StsUnmatchedFormats, "cvShiftDFT", "Source and Destination arrays must have the same format", __FILE__, __LINE__ )
|
||||
|
||||
cvCopy(q3, d1)
|
||||
cvCopy(q4, d2)
|
||||
cvCopy(q1, d3)
|
||||
cvCopy(q2, d4)
|
||||
|
||||
else:
|
||||
cvCopy(q3, tmp)
|
||||
cvCopy(q1, q3)
|
||||
cvCopy(tmp, q1)
|
||||
cvCopy(q4, tmp)
|
||||
cvCopy(q2, q4)
|
||||
cvCopy(tmp, q2)
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
im = cvLoadImage( sys.argv[1], CV_LOAD_IMAGE_GRAYSCALE)
|
||||
|
||||
realInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1)
|
||||
imaginaryInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 1)
|
||||
complexInput = cvCreateImage( cvGetSize(im), IPL_DEPTH_64F, 2)
|
||||
|
||||
cvScale(im, realInput, 1.0, 0.0)
|
||||
cvZero(imaginaryInput)
|
||||
cvMerge(realInput, imaginaryInput, None, None, complexInput)
|
||||
|
||||
dft_M = cvGetOptimalDFTSize( im.height - 1 )
|
||||
dft_N = cvGetOptimalDFTSize( im.width - 1 )
|
||||
|
||||
dft_A = cvCreateMat( dft_M, dft_N, CV_64FC2 )
|
||||
image_Re = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1)
|
||||
image_Im = cvCreateImage( cvSize(dft_N, dft_M), IPL_DEPTH_64F, 1)
|
||||
|
||||
# copy A to dft_A and pad dft_A with zeros
|
||||
tmp = cvGetSubRect( dft_A, cvRect(0,0, im.width, im.height))
|
||||
cvCopy( complexInput, tmp, None )
|
||||
if(dft_A.width > im.width):
|
||||
tmp = cvGetSubRect( dft_A, cvRect(im.width,0, dft_N - im.width, im.height))
|
||||
cvZero( tmp )
|
||||
|
||||
# no need to pad bottom part of dft_A with zeros because of
|
||||
# use nonzero_rows parameter in cvDFT() call below
|
||||
|
||||
cvDFT( dft_A, dft_A, CV_DXT_FORWARD, complexInput.height )
|
||||
|
||||
cvNamedWindow("win", 0)
|
||||
cvNamedWindow("magnitude", 0)
|
||||
cvShowImage("win", im)
|
||||
|
||||
# Split Fourier in real and imaginary parts
|
||||
cvSplit( dft_A, image_Re, image_Im, None, None )
|
||||
|
||||
# Compute the magnitude of the spectrum Mag = sqrt(Re^2 + Im^2)
|
||||
cvPow( image_Re, image_Re, 2.0)
|
||||
cvPow( image_Im, image_Im, 2.0)
|
||||
cvAdd( image_Re, image_Im, image_Re, None)
|
||||
cvPow( image_Re, image_Re, 0.5 )
|
||||
|
||||
# Compute log(1 + Mag)
|
||||
cvAddS( image_Re, cvScalarAll(1.0), image_Re, None ) # 1 + Mag
|
||||
cvLog( image_Re, image_Re ) # log(1 + Mag)
|
||||
|
||||
|
||||
# Rearrange the quadrants of Fourier image so that the origin is at
|
||||
# the image center
|
||||
cvShiftDFT( image_Re, image_Re )
|
||||
|
||||
min, max, pt1, pt2 = cvMinMaxLoc(image_Re)
|
||||
cvScale(image_Re, image_Re, 1.0/(max-min), 1.0*(-min)/(max-min))
|
||||
cvShowImage("magnitude", image_Re)
|
||||
|
||||
cvWaitKey(0)
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
|
||||
wndname = "Distance transform";
|
||||
tbarname = "Threshold";
|
||||
|
||||
# The output images
|
||||
dist = 0;
|
||||
dist8u1 = 0;
|
||||
dist8u2 = 0;
|
||||
dist8u = 0;
|
||||
dist32s = 0;
|
||||
|
||||
gray = 0;
|
||||
edge = 0;
|
||||
|
||||
# define a trackbar callback
|
||||
def on_trackbar( edge_thresh ):
|
||||
|
||||
cvThreshold( gray, edge, float(edge_thresh), float(edge_thresh), CV_THRESH_BINARY );
|
||||
#Distance transform
|
||||
cvDistTransform( edge, dist, CV_DIST_L2, CV_DIST_MASK_5, None, None );
|
||||
|
||||
cvConvertScale( dist, dist, 5000.0, 0 );
|
||||
cvPow( dist, dist, 0.5 );
|
||||
|
||||
cvConvertScale( dist, dist32s, 1.0, 0.5 );
|
||||
cvAndS( dist32s, cvScalarAll(255), dist32s, None );
|
||||
cvConvertScale( dist32s, dist8u1, 1, 0 );
|
||||
cvConvertScale( dist32s, dist32s, -1, 0 );
|
||||
cvAddS( dist32s, cvScalarAll(255), dist32s, None );
|
||||
cvConvertScale( dist32s, dist8u2, 1, 0 );
|
||||
cvMerge( dist8u1, dist8u2, dist8u2, None, dist8u );
|
||||
cvShowImage( wndname, dist8u );
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
edge_thresh = 100;
|
||||
|
||||
filename = "../c/stuff.jpg"
|
||||
if len(sys.argv) > 1:
|
||||
filename = sys.argv[1]
|
||||
|
||||
gray = cvLoadImage( filename, 0 )
|
||||
if not gray:
|
||||
print "Failed to load %s" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
# Create the output image
|
||||
dist = cvCreateImage( cvSize(gray.width,gray.height), IPL_DEPTH_32F, 1 );
|
||||
dist8u1 = cvCloneImage( gray );
|
||||
dist8u2 = cvCloneImage( gray );
|
||||
dist8u = cvCreateImage( cvSize(gray.width,gray.height), IPL_DEPTH_8U, 3 );
|
||||
dist32s = cvCreateImage( cvSize(gray.width,gray.height), IPL_DEPTH_32S, 1 );
|
||||
|
||||
# Convert to grayscale
|
||||
edge = cvCloneImage( gray );
|
||||
|
||||
# Create a window
|
||||
cvNamedWindow( wndname, 1 );
|
||||
|
||||
# create a toolbar
|
||||
cvCreateTrackbar( tbarname, wndname, edge_thresh, 255, on_trackbar );
|
||||
|
||||
# Show the image
|
||||
on_trackbar(edge_thresh);
|
||||
|
||||
# Wait for a key stroke; the same function arranges events processing
|
||||
cvWaitKey(0);
|
||||
Executable
+164
@@ -0,0 +1,164 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
print "OpenCV Python version of drawing"
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
# for making random numbers
|
||||
from random import Random
|
||||
|
||||
def random_color (random):
|
||||
"""
|
||||
Return a random color
|
||||
"""
|
||||
icolor = random.randint (0, 0xFFFFFF)
|
||||
return cv.cvScalar (icolor & 0xff, (icolor >> 8) & 0xff, (icolor >> 16) & 0xff)
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
# some "constants"
|
||||
width = 1000
|
||||
height = 700
|
||||
window_name = "Drawing Demo"
|
||||
number = 100
|
||||
delay = 5
|
||||
line_type = cv.CV_AA # change it to 8 to see non-antialiased graphics
|
||||
|
||||
# create the source image
|
||||
image = cv.cvCreateImage (cv.cvSize (width, height), 8, 3)
|
||||
|
||||
# create window and display the original picture in it
|
||||
highgui.cvNamedWindow (window_name, 1)
|
||||
cv.cvSetZero (image)
|
||||
highgui.cvShowImage (window_name, image)
|
||||
|
||||
# create the random number
|
||||
random = Random ()
|
||||
|
||||
# draw some lines
|
||||
for i in range (number):
|
||||
pt1 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
pt2 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
cv.cvLine (image, pt1, pt2,
|
||||
random_color (random),
|
||||
random.randrange (0, 10),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# draw some rectangles
|
||||
for i in range (number):
|
||||
pt1 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
pt2 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
cv.cvRectangle (image, pt1, pt2,
|
||||
random_color (random),
|
||||
random.randrange (-1, 9),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# draw some ellipes
|
||||
for i in range (number):
|
||||
pt1 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
sz = cv.cvSize (random.randrange (0, 200),
|
||||
random.randrange (0, 200))
|
||||
angle = random.randrange (0, 1000) * 0.180
|
||||
cv.cvEllipse (image, pt1, sz, angle, angle - 100, angle + 200,
|
||||
random_color (random),
|
||||
random.randrange (-1, 9),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# init the list of polylines
|
||||
nb_polylines = 2
|
||||
polylines_size = 3
|
||||
pt = [0,] * nb_polylines
|
||||
for a in range (nb_polylines):
|
||||
pt [a] = [0,] * polylines_size
|
||||
|
||||
# draw some polylines
|
||||
for i in range (number):
|
||||
for a in range (nb_polylines):
|
||||
for b in range (polylines_size):
|
||||
pt [a][b] = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
cv.cvPolyLine (image, pt, 1,
|
||||
random_color (random),
|
||||
random.randrange (1, 9),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# draw some filled polylines
|
||||
for i in range (number):
|
||||
for a in range (nb_polylines):
|
||||
for b in range (polylines_size):
|
||||
pt [a][b] = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
cv.cvFillPoly (image, pt,
|
||||
random_color (random),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# draw some circles
|
||||
for i in range (number):
|
||||
pt1 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
cv.cvCircle (image, pt1, random.randrange (0, 300),
|
||||
random_color (random),
|
||||
random.randrange (-1, 9),
|
||||
line_type, 0)
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# draw some text
|
||||
for i in range (number):
|
||||
pt1 = cv.cvPoint (random.randrange (-width, 2 * width),
|
||||
random.randrange (-height, 2 * height))
|
||||
font = cv.cvInitFont (random.randrange (0, 8),
|
||||
random.randrange (0, 100) * 0.05 + 0.01,
|
||||
random.randrange (0, 100) * 0.05 + 0.01,
|
||||
random.randrange (0, 5) * 0.1,
|
||||
random.randrange (0, 10),
|
||||
line_type)
|
||||
|
||||
cv.cvPutText (image, "Testing text rendering!",
|
||||
pt1, font,
|
||||
random_color (random))
|
||||
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# prepare a text, and get it's properties
|
||||
font = cv.cvInitFont (cv.CV_FONT_HERSHEY_COMPLEX,
|
||||
3, 3, 0.0, 5, line_type)
|
||||
text_size, ymin = cv.cvGetTextSize ("OpenCV forever!", font)
|
||||
pt1.x = (width - text_size.width) / 2
|
||||
pt1.y = (height + text_size.height) / 2
|
||||
image2 = cv.cvCloneImage(image)
|
||||
|
||||
# now, draw some OpenCV pub ;-)
|
||||
for i in range (255):
|
||||
cv.cvSubS (image2, cv.cvScalarAll (i), image, None)
|
||||
cv.cvPutText (image, "OpenCV forever!",
|
||||
pt1, font, cv.cvScalar (255, i, i))
|
||||
highgui.cvShowImage (window_name, image)
|
||||
highgui.cvWaitKey (delay)
|
||||
|
||||
# wait some key to end
|
||||
highgui.cvWaitKey (0)
|
||||
Executable
+64
@@ -0,0 +1,64 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
print "OpenCV Python version of edge"
|
||||
|
||||
import sys
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
# some definitions
|
||||
win_name = "Edge"
|
||||
trackbar_name = "Threshold"
|
||||
|
||||
# the callback on the trackbar
|
||||
def on_trackbar (position):
|
||||
|
||||
cv.cvSmooth (gray, edge, cv.CV_BLUR, 3, 3, 0)
|
||||
cv.cvNot (gray, edge)
|
||||
|
||||
# run the edge dector on gray scale
|
||||
cv.cvCanny (gray, edge, position, position * 3, 3)
|
||||
|
||||
# reset
|
||||
cv.cvSetZero (col_edge)
|
||||
|
||||
# copy edge points
|
||||
cv.cvCopy (image, col_edge, edge)
|
||||
|
||||
# show the image
|
||||
highgui.cvShowImage (win_name, col_edge)
|
||||
|
||||
if __name__ == '__main__':
|
||||
filename = "../c/fruits.jpg"
|
||||
|
||||
if len(sys.argv)>1:
|
||||
filename = sys.argv[1]
|
||||
|
||||
# load the image gived on the command line
|
||||
image = highgui.cvLoadImage (filename)
|
||||
|
||||
if not image:
|
||||
print "Error loading image '%s'" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
# create the output image
|
||||
col_edge = cv.cvCreateImage (cv.cvSize (image.width, image.height), 8, 3)
|
||||
|
||||
# convert to grayscale
|
||||
gray = cv.cvCreateImage (cv.cvSize (image.width, image.height), 8, 1)
|
||||
edge = cv.cvCreateImage (cv.cvSize (image.width, image.height), 8, 1)
|
||||
cv.cvCvtColor (image, gray, cv.CV_BGR2GRAY)
|
||||
|
||||
# create the window
|
||||
highgui.cvNamedWindow (win_name, highgui.CV_WINDOW_AUTOSIZE)
|
||||
|
||||
# create the trackbar
|
||||
highgui.cvCreateTrackbar (trackbar_name, win_name, 1, 100, on_trackbar)
|
||||
|
||||
# show the image
|
||||
on_trackbar (0)
|
||||
|
||||
# wait a key pressed to end
|
||||
highgui.cvWaitKey (0)
|
||||
Executable
+128
@@ -0,0 +1,128 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
This program is demonstration for face and object detection using haar-like features.
|
||||
The program finds faces in a camera image or video stream and displays a red box around them.
|
||||
|
||||
Original C implementation by: ?
|
||||
Python implementation by: Roman Stanchak
|
||||
"""
|
||||
import sys
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
|
||||
|
||||
# Global Variables
|
||||
cascade = None
|
||||
storage = cvCreateMemStorage(0)
|
||||
cascade_name = "../../data/haarcascades/haarcascade_frontalface_alt.xml"
|
||||
input_name = "../c/lena.jpg"
|
||||
|
||||
# Parameters for haar detection
|
||||
# From the API:
|
||||
# The default parameters (scale_factor=1.1, min_neighbors=3, flags=0) are tuned
|
||||
# for accurate yet slow object detection. For a faster operation on real video
|
||||
# images the settings are:
|
||||
# scale_factor=1.2, min_neighbors=2, flags=CV_HAAR_DO_CANNY_PRUNING,
|
||||
# min_size=<minimum possible face size
|
||||
min_size = cvSize(20,20)
|
||||
image_scale = 1.3
|
||||
haar_scale = 1.2
|
||||
min_neighbors = 2
|
||||
haar_flags = 0
|
||||
|
||||
|
||||
def detect_and_draw( img ):
|
||||
# allocate temporary images
|
||||
gray = cvCreateImage( cvSize(img.width,img.height), 8, 1 )
|
||||
small_img = cvCreateImage((cvRound(img.width/image_scale),
|
||||
cvRound (img.height/image_scale)), 8, 1 )
|
||||
|
||||
# convert color input image to grayscale
|
||||
cvCvtColor( img, gray, CV_BGR2GRAY )
|
||||
|
||||
# scale input image for faster processing
|
||||
cvResize( gray, small_img, CV_INTER_LINEAR )
|
||||
|
||||
cvEqualizeHist( small_img, small_img )
|
||||
|
||||
cvClearMemStorage( storage )
|
||||
|
||||
if( cascade ):
|
||||
t = cvGetTickCount()
|
||||
faces = cvHaarDetectObjects( small_img, cascade, storage,
|
||||
haar_scale, min_neighbors, haar_flags, min_size )
|
||||
t = cvGetTickCount() - t
|
||||
print "detection time = %gms" % (t/(cvGetTickFrequency()*1000.))
|
||||
if faces:
|
||||
for face_rect in faces:
|
||||
# the input to cvHaarDetectObjects was resized, so scale the
|
||||
# bounding box of each face and convert it to two CvPoints
|
||||
pt1 = cvPoint( int(face_rect.x*image_scale), int(face_rect.y*image_scale))
|
||||
pt2 = cvPoint( int((face_rect.x+face_rect.width)*image_scale),
|
||||
int((face_rect.y+face_rect.height)*image_scale) )
|
||||
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 )
|
||||
|
||||
cvShowImage( "result", img )
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
if len(sys.argv) > 1:
|
||||
|
||||
if sys.argv[1].startswith("--cascade="):
|
||||
cascade_name = sys.argv[1][ len("--cascade="): ]
|
||||
if len(sys.argv) > 2:
|
||||
input_name = sys.argv[2]
|
||||
|
||||
elif sys.argv[1] == "--help" or sys.argv[1] == "-h":
|
||||
print "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n"
|
||||
sys.exit(-1)
|
||||
|
||||
else:
|
||||
input_name = sys.argv[1]
|
||||
|
||||
# the OpenCV API says this function is obsolete, but we can't
|
||||
# cast the output of cvLoad to a HaarClassifierCascade, so use this anyways
|
||||
# the size parameter is ignored
|
||||
cascade = cvLoadHaarClassifierCascade( cascade_name, cvSize(1,1) )
|
||||
|
||||
if not cascade:
|
||||
print "ERROR: Could not load classifier cascade"
|
||||
sys.exit(-1)
|
||||
|
||||
|
||||
if input_name.isdigit():
|
||||
capture = cvCreateCameraCapture( int(input_name) )
|
||||
else:
|
||||
capture = cvCreateFileCapture( input_name )
|
||||
|
||||
cvNamedWindow( "result", 1 )
|
||||
|
||||
if capture:
|
||||
frame_copy = None
|
||||
while True:
|
||||
frame = cvQueryFrame( capture )
|
||||
if not frame:
|
||||
cvWaitKey(0)
|
||||
break
|
||||
if not frame_copy:
|
||||
frame_copy = cvCreateImage( cvSize(frame.width,frame.height),
|
||||
IPL_DEPTH_8U, frame.nChannels )
|
||||
if frame.origin == IPL_ORIGIN_TL:
|
||||
cvCopy( frame, frame_copy )
|
||||
else:
|
||||
cvFlip( frame, frame_copy, 0 )
|
||||
|
||||
detect_and_draw( frame_copy )
|
||||
|
||||
if( cvWaitKey( 10 ) >= 0 ):
|
||||
break
|
||||
|
||||
else:
|
||||
image = cvLoadImage( input_name, 1 )
|
||||
|
||||
if image:
|
||||
detect_and_draw( image )
|
||||
cvWaitKey(0)
|
||||
|
||||
cvDestroyWindow("result")
|
||||
Executable
+160
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
import random
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
|
||||
color_img0=None;
|
||||
mask=None;
|
||||
color_img=None;
|
||||
gray_img0 = None;
|
||||
gray_img = None;
|
||||
ffill_case = 1;
|
||||
lo_diff = 20
|
||||
up_diff = 20;
|
||||
connectivity = 4;
|
||||
is_color = 1;
|
||||
is_mask = 0;
|
||||
new_mask_val = 255;
|
||||
|
||||
def update_lo( pos ):
|
||||
lo_diff = pos
|
||||
def update_up( pos ):
|
||||
up_diff = pos
|
||||
|
||||
def on_mouse( event, x, y, flags, param ):
|
||||
|
||||
if( not color_img ):
|
||||
return;
|
||||
|
||||
if event==CV_EVENT_LBUTTONDOWN:
|
||||
comp = CvConnectedComp()
|
||||
my_mask = None
|
||||
seed = cvPoint(x,y);
|
||||
if ffill_case==0:
|
||||
lo = up = 0
|
||||
flags = connectivity + (new_mask_val << 8)
|
||||
else:
|
||||
lo = lo_diff;
|
||||
up = up_diff;
|
||||
flags = connectivity + (new_mask_val << 8) + CV_FLOODFILL_FIXED_RANGE
|
||||
b = random.randint(0,255)
|
||||
g = random.randint(0,255)
|
||||
r = random.randint(0,255)
|
||||
|
||||
if( is_mask ):
|
||||
my_mask = mask
|
||||
cvThreshold( mask, mask, 1, 128, CV_THRESH_BINARY );
|
||||
|
||||
if( is_color ):
|
||||
|
||||
color = CV_RGB( r, g, b );
|
||||
cvFloodFill( color_img, seed, color, CV_RGB( lo, lo, lo ),
|
||||
CV_RGB( up, up, up ), comp, flags, my_mask );
|
||||
cvShowImage( "image", color_img );
|
||||
|
||||
else:
|
||||
|
||||
brightness = cvRealScalar((r*2 + g*7 + b + 5)/10);
|
||||
cvFloodFill( gray_img, seed, brightness, cvRealScalar(lo),
|
||||
cvRealScalar(up), comp, flags, my_mask );
|
||||
cvShowImage( "image", gray_img );
|
||||
|
||||
|
||||
print "%g pixels were repainted" % comp.area;
|
||||
|
||||
if( is_mask ):
|
||||
cvShowImage( "mask", mask );
|
||||
|
||||
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
filename = "../c/fruits.jpg"
|
||||
if len(sys.argv)>1:
|
||||
filename=argv[1]
|
||||
|
||||
color_img0 = cvLoadImage(filename,1)
|
||||
if not color_img0:
|
||||
print "Could not open %s" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
print "Hot keys:"
|
||||
print "\tESC - quit the program"
|
||||
print "\tc - switch color/grayscale mode"
|
||||
print "\tm - switch mask mode"
|
||||
print "\tr - restore the original image"
|
||||
print "\ts - use null-range floodfill"
|
||||
print "\tf - use gradient floodfill with fixed(absolute) range"
|
||||
print "\tg - use gradient floodfill with floating(relative) range"
|
||||
print "\t4 - use 4-connectivity mode"
|
||||
print "\t8 - use 8-connectivity mode"
|
||||
|
||||
color_img = cvCloneImage( color_img0 );
|
||||
gray_img0 = cvCreateImage( cvSize(color_img.width, color_img.height), 8, 1 );
|
||||
cvCvtColor( color_img, gray_img0, CV_BGR2GRAY );
|
||||
gray_img = cvCloneImage( gray_img0 );
|
||||
mask = cvCreateImage( cvSize(color_img.width + 2, color_img.height + 2), 8, 1 );
|
||||
|
||||
cvNamedWindow( "image", 1 );
|
||||
cvCreateTrackbar( "lo_diff", "image", lo_diff, 255, update_lo);
|
||||
cvCreateTrackbar( "up_diff", "image", up_diff, 255, update_up);
|
||||
|
||||
cvSetMouseCallback( "image", on_mouse );
|
||||
|
||||
while True:
|
||||
if( is_color ):
|
||||
cvShowImage( "image", color_img );
|
||||
else:
|
||||
cvShowImage( "image", gray_img );
|
||||
|
||||
c = cvWaitKey(0);
|
||||
if c=='\x1b':
|
||||
print("Exiting ...");
|
||||
sys.exit(0)
|
||||
elif c=='c':
|
||||
if( is_color ):
|
||||
|
||||
print("Grayscale mode is set");
|
||||
cvCvtColor( color_img, gray_img, CV_BGR2GRAY );
|
||||
is_color = 0;
|
||||
|
||||
else:
|
||||
|
||||
print("Color mode is set");
|
||||
cvCopy( color_img0, color_img, None );
|
||||
cvZero( mask );
|
||||
is_color = 1;
|
||||
|
||||
elif c=='m':
|
||||
if( is_mask ):
|
||||
cvDestroyWindow( "mask" );
|
||||
is_mask = 0;
|
||||
|
||||
else:
|
||||
cvNamedWindow( "mask", 0 );
|
||||
cvZero( mask );
|
||||
cvShowImage( "mask", mask );
|
||||
is_mask = 1;
|
||||
|
||||
elif c=='r':
|
||||
print("Original image is restored");
|
||||
cvCopy( color_img0, color_img, None );
|
||||
cvCopy( gray_img0, gray_img, None );
|
||||
cvZero( mask );
|
||||
elif c=='s':
|
||||
print("Simple floodfill mode is set");
|
||||
ffill_case = 0;
|
||||
elif c=='f':
|
||||
print("Fixed Range floodfill mode is set");
|
||||
ffill_case = 1;
|
||||
elif c=='g':
|
||||
print("Gradient (floating range) floodfill mode is set");
|
||||
ffill_case = 2;
|
||||
elif c=='4':
|
||||
print("4-connectivity mode is set");
|
||||
connectivity = 4;
|
||||
elif c=='8':
|
||||
print("8-connectivity mode is set");
|
||||
connectivity = 8;
|
||||
Executable
+125
@@ -0,0 +1,125 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
This program is demonstration for ellipse fitting. Program finds
|
||||
contours and approximate it by ellipses.
|
||||
|
||||
Trackbar specify threshold parametr.
|
||||
|
||||
White lines is contours. Red lines is fitting ellipses.
|
||||
|
||||
Original C implementation by: Denis Burenkov.
|
||||
Python implementation by: Roman Stanchak
|
||||
"""
|
||||
|
||||
import sys
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
image02 = None
|
||||
image03 = None
|
||||
image04 = None
|
||||
|
||||
def process_image( slider_pos ):
|
||||
"""
|
||||
Define trackbar callback functon. This function find contours,
|
||||
draw it and approximate it by ellipses.
|
||||
"""
|
||||
stor = cv.cvCreateMemStorage(0);
|
||||
|
||||
# Threshold the source image. This needful for cv.cvFindContours().
|
||||
cv.cvThreshold( image03, image02, slider_pos, 255, cv.CV_THRESH_BINARY );
|
||||
|
||||
# Find all contours.
|
||||
nb_contours, cont = cv.cvFindContours (image02,
|
||||
stor,
|
||||
cv.sizeof_CvContour,
|
||||
cv.CV_RETR_LIST,
|
||||
cv.CV_CHAIN_APPROX_NONE,
|
||||
cv.cvPoint (0,0))
|
||||
|
||||
# Clear images. IPL use.
|
||||
cv.cvZero(image02);
|
||||
cv.cvZero(image04);
|
||||
|
||||
# This cycle draw all contours and approximate it by ellipses.
|
||||
for c in cont.hrange():
|
||||
count = c.total; # This is number point in contour
|
||||
|
||||
# Number point must be more than or equal to 6 (for cv.cvFitEllipse_32f).
|
||||
if( count < 6 ):
|
||||
continue;
|
||||
|
||||
# Alloc memory for contour point set.
|
||||
PointArray = cv.cvCreateMat(1, count, cv.CV_32SC2)
|
||||
PointArray2D32f= cv.cvCreateMat( 1, count, cv.CV_32FC2)
|
||||
|
||||
# Get contour point set.
|
||||
cv.cvCvtSeqToArray(c, PointArray, cv.cvSlice(0, cv.CV_WHOLE_SEQ_END_INDEX));
|
||||
|
||||
# Convert CvPoint set to CvBox2D32f set.
|
||||
cv.cvConvert( PointArray, PointArray2D32f )
|
||||
|
||||
box = cv.CvBox2D()
|
||||
|
||||
# Fits ellipse to current contour.
|
||||
box = cv.cvFitEllipse2(PointArray2D32f);
|
||||
|
||||
# Draw current contour.
|
||||
cv.cvDrawContours(image04, c, cv.CV_RGB(255,255,255), cv.CV_RGB(255,255,255),0,1,8,cv.cvPoint(0,0));
|
||||
|
||||
# Convert ellipse data from float to integer representation.
|
||||
center = cv.CvPoint()
|
||||
size = cv.CvSize()
|
||||
center.x = cv.cvRound(box.center.x);
|
||||
center.y = cv.cvRound(box.center.y);
|
||||
size.width = cv.cvRound(box.size.width*0.5);
|
||||
size.height = cv.cvRound(box.size.height*0.5);
|
||||
box.angle = -box.angle;
|
||||
|
||||
# Draw ellipse.
|
||||
cv.cvEllipse(image04, center, size,
|
||||
box.angle, 0, 360,
|
||||
cv.CV_RGB(0,0,255), 1, cv.CV_AA, 0);
|
||||
|
||||
# Show image. HighGUI use.
|
||||
highgui.cvShowImage( "Result", image04 );
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
argc = len(sys.argv)
|
||||
filename = "../c/stuff.jpg"
|
||||
if(argc == 2):
|
||||
filename = sys.argv[1]
|
||||
|
||||
slider_pos = 70
|
||||
|
||||
# load image and force it to be grayscale
|
||||
image03 = highgui.cvLoadImage(filename, 0)
|
||||
if not image03:
|
||||
print "Could not load image " + filename
|
||||
sys.exit(-1)
|
||||
|
||||
# Create the destination images
|
||||
image02 = cv.cvCloneImage( image03 );
|
||||
image04 = cv.cvCloneImage( image03 );
|
||||
|
||||
# Create windows.
|
||||
highgui.cvNamedWindow("Source", 1);
|
||||
highgui.cvNamedWindow("Result", 1);
|
||||
|
||||
# Show the image.
|
||||
highgui.cvShowImage("Source", image03);
|
||||
|
||||
# Create toolbars. HighGUI use.
|
||||
highgui.cvCreateTrackbar( "Threshold", "Result", slider_pos, 255, process_image );
|
||||
|
||||
|
||||
process_image( 1 );
|
||||
|
||||
#Wait for a key stroke; the same function arranges events processing
|
||||
print "Press any key to exit"
|
||||
highgui.cvWaitKey(0);
|
||||
|
||||
highgui.cvDestroyWindow("Source");
|
||||
highgui.cvDestroyWindow("Result");
|
||||
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python
|
||||
# This is a standalone program. Pass an image name as a first parameter of the program.
|
||||
|
||||
import sys
|
||||
from math import sin,cos,sqrt
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
|
||||
# toggle between CV_HOUGH_STANDARD and CV_HOUGH_PROBILISTIC
|
||||
USE_STANDARD=0
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = "../../docs/ref/pics/building.jpg"
|
||||
if len(sys.argv)>1:
|
||||
filename = sys.argv[1]
|
||||
|
||||
src=cvLoadImage(filename, 0);
|
||||
if not src:
|
||||
print "Error opening image %s" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
dst = cvCreateImage( cvGetSize(src), 8, 1 );
|
||||
color_dst = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
storage = cvCreateMemStorage(0);
|
||||
lines = 0;
|
||||
cvCanny( src, dst, 50, 200, 3 );
|
||||
cvCvtColor( dst, color_dst, CV_GRAY2BGR );
|
||||
|
||||
if USE_STANDARD:
|
||||
lines = cvHoughLines2( dst, storage, CV_HOUGH_STANDARD, 1, CV_PI/180, 100, 0, 0 );
|
||||
|
||||
for i in range(min(lines.total, 100)):
|
||||
line = lines[i]
|
||||
rho = line[0];
|
||||
theta = line[1];
|
||||
pt1 = CvPoint();
|
||||
pt2 = CvPoint();
|
||||
a = cos(theta);
|
||||
b = sin(theta);
|
||||
x0 = a*rho
|
||||
y0 = b*rho
|
||||
pt1.x = cvRound(x0 + 1000*(-b));
|
||||
pt1.y = cvRound(y0 + 1000*(a));
|
||||
pt2.x = cvRound(x0 - 1000*(-b));
|
||||
pt2.y = cvRound(y0 - 1000*(a));
|
||||
cvLine( color_dst, pt1, pt2, CV_RGB(255,0,0), 3, 8 );
|
||||
|
||||
else:
|
||||
lines = cvHoughLines2( dst, storage, CV_HOUGH_PROBABILISTIC, 1, CV_PI/180, 50, 50, 10 );
|
||||
for line in lines:
|
||||
cvLine( color_dst, line[0], line[1], CV_RGB(255,0,0), 3, 8 );
|
||||
|
||||
cvNamedWindow( "Source", 1 );
|
||||
cvShowImage( "Source", src );
|
||||
|
||||
cvNamedWindow( "Hough", 1 );
|
||||
cvShowImage( "Hough", color_dst );
|
||||
|
||||
cvWaitKey(0);
|
||||
Executable
+73
@@ -0,0 +1,73 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
inpaint_mask = None
|
||||
img0 = None
|
||||
img = None
|
||||
inpainted = None
|
||||
prev_pt = cvPoint(-1,-1)
|
||||
|
||||
def on_mouse( event, x, y, flags, param ):
|
||||
global prev_pt
|
||||
if not img:
|
||||
return
|
||||
|
||||
if event == CV_EVENT_LBUTTONUP or not (flags & CV_EVENT_FLAG_LBUTTON):
|
||||
prev_pt = cvPoint(-1,-1)
|
||||
elif event == CV_EVENT_LBUTTONDOWN:
|
||||
prev_pt = cvPoint(x,y)
|
||||
elif event == CV_EVENT_MOUSEMOVE and (flags & CV_EVENT_FLAG_LBUTTON) :
|
||||
pt = cvPoint(x,y)
|
||||
if prev_pt.x < 0:
|
||||
prev_pt = pt
|
||||
cvLine( inpaint_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 )
|
||||
cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 )
|
||||
prev_pt = pt
|
||||
cvShowImage( "image", img )
|
||||
|
||||
if __name__=="__main__":
|
||||
filename = "../c/fruits.jpg"
|
||||
if len(sys.argv) >= 2:
|
||||
filename = sys.argv[1]
|
||||
|
||||
img0 = cvLoadImage(filename,-1)
|
||||
if not img0:
|
||||
print "Can't open image '%s'" % filename
|
||||
sys.exit(1)
|
||||
|
||||
print "Hot keys:"
|
||||
print "\tESC - quit the program"
|
||||
print "\tr - restore the original image"
|
||||
print "\ti or ENTER - run inpainting algorithm"
|
||||
print "\t\t(before running it, paint something on the image)"
|
||||
|
||||
cvNamedWindow( "image", 1 )
|
||||
|
||||
img = cvCloneImage( img0 )
|
||||
inpainted = cvCloneImage( img0 )
|
||||
inpaint_mask = cvCreateImage( cvGetSize(img), 8, 1 )
|
||||
|
||||
cvZero( inpaint_mask )
|
||||
cvZero( inpainted )
|
||||
cvShowImage( "image", img )
|
||||
cvShowImage( "watershed transform", inpainted )
|
||||
cvSetMouseCallback( "image", on_mouse, None )
|
||||
|
||||
while True:
|
||||
c = cvWaitKey(0)
|
||||
|
||||
if c == '\x1b' or c == 'q':
|
||||
break
|
||||
|
||||
if c == 'r':
|
||||
cvZero( inpaint_mask )
|
||||
cvCopy( img0, img )
|
||||
cvShowImage( "image", img )
|
||||
|
||||
if c == 'i' or c == '\012':
|
||||
cvNamedWindow( "inpainted image", 1 )
|
||||
cvInpaint( img, inpaint_mask, inpainted, 3, CV_INPAINT_TELEA )
|
||||
cvShowImage( "inpainted image", inpainted )
|
||||
|
||||
Executable
+92
@@ -0,0 +1,92 @@
|
||||
#!/usr/bin/python
|
||||
"""
|
||||
Tracking of rotating point.
|
||||
Rotation speed is constant.
|
||||
Both state and measurements vectors are 1D (a point angle),
|
||||
Measurement is the real point angle + gaussian noise.
|
||||
The real and the estimated points are connected with yellow line segment,
|
||||
the real and the measured points are connected with red line segment.
|
||||
(if Kalman filter works correctly,
|
||||
the yellow segment should be shorter than the red one).
|
||||
Pressing any key (except ESC) will reset the tracking with a different speed.
|
||||
Pressing ESC will stop the program.
|
||||
"""
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
from math import cos, sin, sqrt
|
||||
|
||||
if __name__ == "__main__":
|
||||
A = [ [1, 1], [0, 1] ]
|
||||
|
||||
img = cvCreateImage( cvSize(500,500), 8, 3 )
|
||||
kalman = cvCreateKalman( 2, 1, 0 )
|
||||
state = cvCreateMat( 2, 1, CV_32FC1 ) # (phi, delta_phi)
|
||||
process_noise = cvCreateMat( 2, 1, CV_32FC1 )
|
||||
measurement = cvCreateMat( 1, 1, CV_32FC1 )
|
||||
rng = cvRNG(-1)
|
||||
code = -1L
|
||||
|
||||
cvZero( measurement )
|
||||
cvNamedWindow( "Kalman", 1 )
|
||||
|
||||
while True:
|
||||
cvRandArr( rng, state, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) )
|
||||
|
||||
kalman.transition_matrix[:] = A
|
||||
cvSetIdentity( kalman.measurement_matrix, cvRealScalar(1) )
|
||||
cvSetIdentity( kalman.process_noise_cov, cvRealScalar(1e-5) )
|
||||
cvSetIdentity( kalman.measurement_noise_cov, cvRealScalar(1e-1) )
|
||||
cvSetIdentity( kalman.error_cov_post, cvRealScalar(1))
|
||||
cvRandArr( rng, kalman.state_post, CV_RAND_NORMAL, cvRealScalar(0), cvRealScalar(0.1) )
|
||||
|
||||
while True:
|
||||
def calc_point(angle):
|
||||
return cvPoint( cvRound(img.width/2 + img.width/3*cos(angle)),
|
||||
cvRound(img.height/2 - img.width/3*sin(angle)))
|
||||
|
||||
state_angle = state[0]
|
||||
state_pt = calc_point(state_angle)
|
||||
|
||||
prediction = cvKalmanPredict( kalman )
|
||||
predict_angle = prediction[0,0]
|
||||
predict_pt = calc_point(predict_angle)
|
||||
|
||||
cvRandArr( rng, measurement, CV_RAND_NORMAL, cvRealScalar(0),
|
||||
cvRealScalar(sqrt(kalman.measurement_noise_cov[0,0])) )
|
||||
|
||||
# generate measurement
|
||||
cvMatMulAdd( kalman.measurement_matrix, state, measurement, measurement )
|
||||
|
||||
measurement_angle = measurement[0,0]
|
||||
measurement_pt = calc_point(measurement_angle)
|
||||
|
||||
# plot points
|
||||
def draw_cross( center, color, d ):
|
||||
cvLine( img, cvPoint( center.x - d, center.y - d ),
|
||||
cvPoint( center.x + d, center.y + d ), color, 1, CV_AA, 0)
|
||||
cvLine( img, cvPoint( center.x + d, center.y - d ),
|
||||
cvPoint( center.x - d, center.y + d ), color, 1, CV_AA, 0 )
|
||||
|
||||
cvZero( img )
|
||||
draw_cross( state_pt, CV_RGB(255,255,255), 3 )
|
||||
draw_cross( measurement_pt, CV_RGB(255,0,0), 3 )
|
||||
draw_cross( predict_pt, CV_RGB(0,255,0), 3 )
|
||||
cvLine( img, state_pt, measurement_pt, CV_RGB(255,0,0), 3, CV_AA, 0 )
|
||||
cvLine( img, state_pt, predict_pt, CV_RGB(255,255,0), 3, CV_AA, 0 )
|
||||
|
||||
cvKalmanCorrect( kalman, measurement )
|
||||
|
||||
cvRandArr( rng, process_noise, CV_RAND_NORMAL, cvRealScalar(0),
|
||||
cvRealScalar(sqrt(kalman.process_noise_cov[0,0])))
|
||||
cvMatMulAdd( kalman.transition_matrix, state, process_noise, state )
|
||||
|
||||
cvShowImage( "Kalman", img )
|
||||
|
||||
code = str(cvWaitKey( 100 ))
|
||||
if( code != '-1'):
|
||||
break
|
||||
|
||||
if( code == '\x1b' or code == 'q' or code == 'Q' ):
|
||||
break
|
||||
|
||||
cvDestroyWindow("Kalman")
|
||||
Executable
+66
@@ -0,0 +1,66 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
from random import randint
|
||||
MAX_CLUSTERS = 5
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
color_tab = [
|
||||
CV_RGB(255,0,0),
|
||||
CV_RGB(0,255,0),
|
||||
CV_RGB(100,100,255),
|
||||
CV_RGB(255,0,255),
|
||||
CV_RGB(255,255,0)]
|
||||
img = cvCreateImage( cvSize( 500, 500 ), 8, 3 )
|
||||
rng = cvRNG(-1)
|
||||
|
||||
cvNamedWindow( "clusters", 1 )
|
||||
|
||||
while True:
|
||||
cluster_count = randint(2, MAX_CLUSTERS)
|
||||
sample_count = randint(1, 1000)
|
||||
points = cvCreateMat( sample_count, 1, CV_32FC2 )
|
||||
clusters = cvCreateMat( sample_count, 1, CV_32SC1 )
|
||||
|
||||
# generate random sample from multigaussian distribution
|
||||
for k in range(cluster_count):
|
||||
center = CvPoint()
|
||||
center.x = cvRandInt(rng)%img.width
|
||||
center.y = cvRandInt(rng)%img.height
|
||||
first = k*sample_count/cluster_count
|
||||
last = sample_count
|
||||
if k != cluster_count:
|
||||
last = (k+1)*sample_count/cluster_count
|
||||
|
||||
point_chunk = cvGetRows(points, first, last)
|
||||
|
||||
cvRandArr( rng, point_chunk, CV_RAND_NORMAL,
|
||||
cvScalar(center.x,center.y,0,0),
|
||||
cvScalar(img.width*0.1,img.height*0.1,0,0))
|
||||
|
||||
|
||||
# shuffle samples
|
||||
cvRandShuffle( points, rng )
|
||||
|
||||
cvKMeans2( points, cluster_count, clusters,
|
||||
cvTermCriteria( CV_TERMCRIT_EPS+CV_TERMCRIT_ITER, 10, 1.0 ))
|
||||
|
||||
cvZero( img )
|
||||
|
||||
for i in range(sample_count):
|
||||
cluster_idx = clusters[i]
|
||||
# a multi channel matrix access returns a scalar of
|
||||
#dimension 4,0, which is not considerate a cvPoint
|
||||
#we have to create a tuple with the first two elements
|
||||
pt = (cvRound(points[i][0]), cvRound(points[i][1]))
|
||||
cvCircle( img, pt, 2, color_tab[cluster_idx], CV_FILLED, CV_AA, 0 )
|
||||
|
||||
cvShowImage( "clusters", img )
|
||||
|
||||
key = cvWaitKey(0)
|
||||
if( key == 27 or key == 'q' or key == 'Q' ): # 'ESC'
|
||||
break
|
||||
|
||||
|
||||
cvDestroyWindow( "clusters" )
|
||||
Executable
+49
@@ -0,0 +1,49 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
if __name__ == "__main__":
|
||||
laplace = None
|
||||
colorlaplace = None
|
||||
planes = [ None, None, None ]
|
||||
capture = None
|
||||
|
||||
if len(sys.argv)==1:
|
||||
capture = cvCreateCameraCapture( 0 )
|
||||
elif len(sys.argv)==2 and sys.argv[1].isdigit():
|
||||
capture = cvCreateCameraCapture( int(sys.argv[1]) )
|
||||
elif len(sys.argv)==2:
|
||||
capture = cvCreateFileCapture( sys.argv[1] )
|
||||
|
||||
if not capture:
|
||||
print "Could not initialize capturing..."
|
||||
sys.exit(-1)
|
||||
|
||||
cvNamedWindow( "Laplacian", 1 )
|
||||
|
||||
while True:
|
||||
frame = cvQueryFrame( capture )
|
||||
if not frame:
|
||||
cvWaitKey(0)
|
||||
break
|
||||
|
||||
if not laplace:
|
||||
for i in range( len(planes) ):
|
||||
planes[i] = cvCreateImage( cvSize(frame.width,frame.height), 8, 1 )
|
||||
laplace = cvCreateImage( cvSize(frame.width,frame.height), IPL_DEPTH_16S, 1 )
|
||||
colorlaplace = cvCreateImage( cvSize(frame.width,frame.height), 8, 3 )
|
||||
|
||||
cvSplit( frame, planes[0], planes[1], planes[2], None )
|
||||
for plane in planes:
|
||||
cvLaplace( plane, laplace, 3 )
|
||||
cvConvertScaleAbs( laplace, plane, 1, 0 )
|
||||
|
||||
cvMerge( planes[0], planes[1], planes[2], None, colorlaplace )
|
||||
|
||||
cvShowImage("Laplacian", colorlaplace )
|
||||
|
||||
if cvWaitKey(10) != -1:
|
||||
break
|
||||
|
||||
cvDestroyWindow("Laplacian")
|
||||
Executable
+227
@@ -0,0 +1,227 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
print "OpenCV Python version of lkdemo"
|
||||
|
||||
import sys
|
||||
|
||||
# import the necessary things for OpenCV
|
||||
from opencv import cv
|
||||
from opencv import highgui
|
||||
|
||||
#############################################################################
|
||||
# some "constants"
|
||||
|
||||
win_size = 10
|
||||
MAX_COUNT = 500
|
||||
|
||||
#############################################################################
|
||||
# some "global" variables
|
||||
|
||||
image = None
|
||||
pt = None
|
||||
add_remove_pt = False
|
||||
flags = 0
|
||||
night_mode = False
|
||||
need_to_init = False
|
||||
# the default parameters
|
||||
quality = 0.01
|
||||
min_distance = 10
|
||||
|
||||
#############################################################################
|
||||
# the mouse callback
|
||||
|
||||
# the callback on the trackbar
|
||||
def on_mouse (event, x, y, flags, param):
|
||||
|
||||
# we will use the global pt and add_remove_pt
|
||||
global pt
|
||||
global add_remove_pt
|
||||
|
||||
if image is None:
|
||||
# not initialized, so skip
|
||||
return
|
||||
|
||||
if event == highgui.CV_EVENT_LBUTTONDOWN:
|
||||
# user has click, so memorize it
|
||||
pt = cv.cvPoint (x, y)
|
||||
add_remove_pt = True
|
||||
|
||||
#############################################################################
|
||||
# so, here is the main part of the program
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
try:
|
||||
# try to get the device number from the command line
|
||||
device = int (sys.argv [1])
|
||||
|
||||
# got it ! so remove it from the arguments
|
||||
del sys.argv [1]
|
||||
except (IndexError, ValueError):
|
||||
# no device number on the command line, assume we want the 1st device
|
||||
device = 0
|
||||
|
||||
if len (sys.argv) == 1:
|
||||
# no argument on the command line, try to use the camera
|
||||
capture = highgui.cvCreateCameraCapture (device)
|
||||
|
||||
else:
|
||||
# we have an argument on the command line,
|
||||
# we can assume this is a file name, so open it
|
||||
capture = highgui.cvCreateFileCapture (sys.argv [1])
|
||||
|
||||
# check that capture device is OK
|
||||
if not capture:
|
||||
print "Error opening capture device"
|
||||
sys.exit (1)
|
||||
|
||||
# display a small howto use it
|
||||
print "Hot keys: \n" \
|
||||
"\tESC - quit the program\n" \
|
||||
"\tr - auto-initialize tracking\n" \
|
||||
"\tc - delete all the points\n" \
|
||||
"\tn - switch the \"night\" mode on/off\n" \
|
||||
"To add/remove a feature point click it\n"
|
||||
|
||||
# first, create the necessary windows
|
||||
highgui.cvNamedWindow ('LkDemo', highgui.CV_WINDOW_AUTOSIZE)
|
||||
|
||||
# register the mouse callback
|
||||
highgui.cvSetMouseCallback ('LkDemo', on_mouse, None)
|
||||
|
||||
while 1:
|
||||
# do forever
|
||||
|
||||
# 1. capture the current image
|
||||
frame = highgui.cvQueryFrame (capture)
|
||||
if frame is None:
|
||||
# no image captured... end the processing
|
||||
break
|
||||
|
||||
if image is None:
|
||||
# create the images we need
|
||||
image = cv.cvCreateImage (cv.cvGetSize (frame), 8, 3)
|
||||
grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
|
||||
prev_grey = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
|
||||
pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
|
||||
prev_pyramid = cv.cvCreateImage (cv.cvGetSize (frame), 8, 1)
|
||||
eig = cv.cvCreateImage (cv.cvGetSize (frame), cv.IPL_DEPTH_32F, 1)
|
||||
temp = cv.cvCreateImage (cv.cvGetSize (frame), cv.IPL_DEPTH_32F, 1)
|
||||
points = [[], []]
|
||||
|
||||
# copy the frame, so we can draw on it
|
||||
cv.cvCopy (frame, image)
|
||||
|
||||
# create a grey version of the image
|
||||
cv.cvCvtColor (image, grey, cv.CV_BGR2GRAY)
|
||||
|
||||
if night_mode:
|
||||
# night mode: only display the points
|
||||
cv.cvSetZero (image)
|
||||
|
||||
if need_to_init:
|
||||
# we want to search all the good points
|
||||
# create the wanted images
|
||||
|
||||
# search the good points
|
||||
points [1] = cv.cvGoodFeaturesToTrack (
|
||||
grey, eig, temp,
|
||||
MAX_COUNT,
|
||||
quality, min_distance, None, 3, 0, 0.04)
|
||||
|
||||
# refine the corner locations
|
||||
cv.cvFindCornerSubPix (
|
||||
grey,
|
||||
points [1],
|
||||
cv.cvSize (win_size, win_size), cv.cvSize (-1, -1),
|
||||
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,
|
||||
20, 0.03))
|
||||
|
||||
elif len (points [0]) > 0:
|
||||
# we have points, so display them
|
||||
|
||||
# calculate the optical flow
|
||||
[points [1], status], something = cv.cvCalcOpticalFlowPyrLK (
|
||||
prev_grey, grey, prev_pyramid, pyramid,
|
||||
points [0], len (points [0]),
|
||||
(win_size, win_size), 3,
|
||||
len (points [0]),
|
||||
None,
|
||||
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER|cv.CV_TERMCRIT_EPS,
|
||||
20, 0.03),
|
||||
flags)
|
||||
|
||||
# initializations
|
||||
point_counter = -1
|
||||
new_points = []
|
||||
|
||||
for the_point in points [1]:
|
||||
# go trough all the points
|
||||
|
||||
# increment the counter
|
||||
point_counter += 1
|
||||
|
||||
if add_remove_pt:
|
||||
# we have a point to add, so see if it is close to
|
||||
# another one. If yes, don't use it
|
||||
dx = pt.x - the_point.x
|
||||
dy = pt.y - the_point.y
|
||||
if dx * dx + dy * dy <= 25:
|
||||
# too close
|
||||
add_remove_pt = 0
|
||||
continue
|
||||
|
||||
if not status [point_counter]:
|
||||
# we will disable this point
|
||||
continue
|
||||
|
||||
# this point is a correct point
|
||||
new_points.append (the_point)
|
||||
|
||||
# draw the current point
|
||||
cv.cvCircle (image,
|
||||
cv.cvPointFrom32f(the_point),
|
||||
3, cv.cvScalar (0, 255, 0, 0),
|
||||
-1, 8, 0)
|
||||
|
||||
# set back the points we keep
|
||||
points [1] = new_points
|
||||
|
||||
if add_remove_pt:
|
||||
# we want to add a point
|
||||
points [1].append (cv.cvPointTo32f (pt))
|
||||
|
||||
# refine the corner locations
|
||||
points [1][-1] = cv.cvFindCornerSubPix (
|
||||
grey,
|
||||
[points [1][-1]],
|
||||
cv.cvSize (win_size, win_size), cv.cvSize (-1, -1),
|
||||
cv.cvTermCriteria (cv.CV_TERMCRIT_ITER | cv.CV_TERMCRIT_EPS,
|
||||
20, 0.03))[0]
|
||||
|
||||
# we are no more in "add_remove_pt" mode
|
||||
add_remove_pt = False
|
||||
|
||||
# swapping
|
||||
prev_grey, grey = grey, prev_grey
|
||||
prev_pyramid, pyramid = pyramid, prev_pyramid
|
||||
points [0], points [1] = points [1], points [0]
|
||||
need_to_init = False
|
||||
|
||||
# we can now display the image
|
||||
highgui.cvShowImage ('LkDemo', image)
|
||||
|
||||
# handle events
|
||||
c = highgui.cvWaitKey (10)
|
||||
|
||||
if c == '\x1b':
|
||||
# user has press the ESC key, so exit
|
||||
break
|
||||
|
||||
# processing depending on the character
|
||||
if c in ['r', 'R']:
|
||||
need_to_init = True
|
||||
elif c in ['c', 'C']:
|
||||
points = [[], []]
|
||||
elif c in ['n', 'N']:
|
||||
night_mode = not night_mode
|
||||
Executable
+44
@@ -0,0 +1,44 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
|
||||
src=None
|
||||
dst=None
|
||||
src2=None
|
||||
|
||||
def on_mouse( event, x, y, flags, param ):
|
||||
|
||||
if( not src ):
|
||||
return;
|
||||
|
||||
if event==CV_EVENT_LBUTTONDOWN:
|
||||
cvLogPolar( src, dst, cvPoint2D32f(x,y), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS );
|
||||
cvLogPolar( dst, src2, cvPoint2D32f(x,y), 40, CV_INTER_LINEAR+CV_WARP_FILL_OUTLIERS+CV_WARP_INVERSE_MAP );
|
||||
cvShowImage( "log-polar", dst );
|
||||
cvShowImage( "inverse log-polar", src2 );
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
filename = "../c/fruits.jpg"
|
||||
if len(sys.argv)>1:
|
||||
filename=argv[1]
|
||||
|
||||
src = cvLoadImage(filename,1)
|
||||
if not src:
|
||||
print "Could not open %s" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
cvNamedWindow( "original",1 );
|
||||
cvNamedWindow( "log-polar", 1 );
|
||||
cvNamedWindow( "inverse log-polar", 1 );
|
||||
|
||||
|
||||
dst = cvCreateImage( cvSize(256,256), 8, 3 );
|
||||
src2 = cvCreateImage( cvGetSize(src), 8, 3 );
|
||||
|
||||
cvSetMouseCallback( "original", on_mouse );
|
||||
on_mouse( CV_EVENT_LBUTTONDOWN, src.width/2, src.height/2, None, None)
|
||||
|
||||
cvShowImage( "original", src );
|
||||
cvWaitKey();
|
||||
Executable
+71
@@ -0,0 +1,71 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
from random import randint
|
||||
|
||||
def minarea_array(img, count):
|
||||
pointMat = cvCreateMat( count, 1, CV_32SC2 )
|
||||
for i in range(count):
|
||||
pointMat[i] = cvPoint( randint(img.width/4, img.width*3/4),
|
||||
randint(img.height/4, img.height*3/4) )
|
||||
|
||||
box = cvMinAreaRect2( pointMat )
|
||||
box_vtx = cvBoxPoints( box )
|
||||
success, center, radius = cvMinEnclosingCircle( pointMat )
|
||||
cvZero( img )
|
||||
for i in range(count):
|
||||
cvCircle( img, cvGet1D(pointMat,i), 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 )
|
||||
|
||||
box_vtx = [cvPointFrom32f(box_vtx[0]),
|
||||
cvPointFrom32f(box_vtx[1]),
|
||||
cvPointFrom32f(box_vtx[2]),
|
||||
cvPointFrom32f(box_vtx[3])]
|
||||
cvCircle( img, cvPointFrom32f(center), cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 )
|
||||
cvPolyLine( img, [box_vtx], 1, CV_RGB(0,255,255), 1, CV_AA )
|
||||
|
||||
|
||||
|
||||
def minarea_seq(img, count, storage):
|
||||
ptseq = cvCreateSeq( CV_SEQ_KIND_GENERIC | CV_32SC2, sizeof_CvContour, sizeof_CvPoint, storage )
|
||||
ptseq = CvSeq_CvPoint.cast( ptseq )
|
||||
for i in range(count):
|
||||
pt0 = cvPoint( randint(img.width/4, img.width*3/4),
|
||||
randint(img.height/4, img.height*3/4) )
|
||||
cvSeqPush( ptseq, pt0 )
|
||||
box = cvMinAreaRect2( ptseq )
|
||||
box_vtx = cvBoxPoints( box )
|
||||
success, center, radius = cvMinEnclosingCircle( ptseq )
|
||||
cvZero( img )
|
||||
for pt in ptseq:
|
||||
cvCircle( img, pt, 2, CV_RGB( 255, 0, 0 ), CV_FILLED, CV_AA, 0 )
|
||||
|
||||
box_vtx = [cvPointFrom32f(box_vtx[0]),
|
||||
cvPointFrom32f(box_vtx[1]),
|
||||
cvPointFrom32f(box_vtx[2]),
|
||||
cvPointFrom32f(box_vtx[3])]
|
||||
cvCircle( img, cvPointFrom32f(center), cvRound(radius), CV_RGB(255, 255, 0), 1, CV_AA, 0 )
|
||||
cvPolyLine( img, [box_vtx], 1, CV_RGB(0,255,255), 1, CV_AA )
|
||||
cvClearMemStorage( storage )
|
||||
|
||||
if __name__ == "__main__":
|
||||
img = cvCreateImage( cvSize( 500, 500 ), 8, 3 );
|
||||
storage = cvCreateMemStorage(0);
|
||||
|
||||
cvNamedWindow( "rect & circle", 1 );
|
||||
|
||||
use_seq=True
|
||||
|
||||
while True:
|
||||
count = randint(1,100)
|
||||
if use_seq:
|
||||
minarea_seq(img, count, storage)
|
||||
else:
|
||||
minarea_array(img, count)
|
||||
|
||||
cvShowImage("rect & circle", img)
|
||||
key = cvWaitKey()
|
||||
if( key == '\x1b' ):
|
||||
break;
|
||||
|
||||
use_seq = not use_seq
|
||||
Executable
+14
@@ -0,0 +1,14 @@
|
||||
#! /usr/bin/env python
|
||||
|
||||
import opencv
|
||||
from opencv import highgui
|
||||
|
||||
cap = highgui.cvCreateFileCapture("../c/tree.avi")
|
||||
img = highgui.cvQueryFrame(cap)
|
||||
print "Got frame of dimensions (", img.width, " x ", img.height, " )"
|
||||
|
||||
highgui.cvNamedWindow("win", highgui.CV_WINDOW_AUTOSIZE)
|
||||
highgui.cvShowImage("win", img)
|
||||
highgui.cvMoveWindow("win", 200, 200)
|
||||
highgui.cvWaitKey(0)
|
||||
|
||||
Executable
+50
@@ -0,0 +1,50 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
src = 0;
|
||||
image = 0;
|
||||
dest = 0;
|
||||
element = 0;
|
||||
element_shape = CV_SHAPE_RECT;
|
||||
global_pos = 0;
|
||||
|
||||
def Opening(pos):
|
||||
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None );
|
||||
cvErode(src,image,element,1);
|
||||
cvDilate(image,dest,element,1);
|
||||
cvShowImage("Opening&Closing window",dest);
|
||||
def Closing(pos):
|
||||
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None );
|
||||
cvDilate(src,image,element,1);
|
||||
cvErode(image,dest,element,1);
|
||||
cvShowImage("Opening&Closing window",dest);
|
||||
def Erosion(pos):
|
||||
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None );
|
||||
cvErode(src,dest,element,1);
|
||||
cvShowImage("Erosion&Dilation window",dest);
|
||||
def Dilation(pos):
|
||||
element = cvCreateStructuringElementEx( pos*2+1, pos*2+1, pos, pos, element_shape, None );
|
||||
cvDilate(src,dest,element,1);
|
||||
cvShowImage("Erosion&Dilation window",dest);
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = "../c/baboon.jpg"
|
||||
if len(sys.argv)==2:
|
||||
filename = sys.argv[1]
|
||||
src = cvLoadImage(filename,1)
|
||||
if not src:
|
||||
sys.exit(-1)
|
||||
image = cvCloneImage(src);
|
||||
dest = cvCloneImage(src);
|
||||
cvNamedWindow("Opening&Closing window",1);
|
||||
cvNamedWindow("Erosion&Dilation window",1);
|
||||
cvShowImage("Opening&Closing window",src);
|
||||
cvShowImage("Erosion&Dilation window",src);
|
||||
cvCreateTrackbar("Open","Opening&Closing window",global_pos,10,Opening);
|
||||
cvCreateTrackbar("Close","Opening&Closing window",global_pos,10,Closing);
|
||||
cvCreateTrackbar("Dilate","Erosion&Dilation window",global_pos,10,Dilation);
|
||||
cvCreateTrackbar("Erode","Erosion&Dilation window",global_pos,10,Erosion);
|
||||
cvWaitKey(0);
|
||||
cvDestroyWindow("Opening&Closing window");
|
||||
cvDestroyWindow("Erosion&Dilation window");
|
||||
Executable
+113
@@ -0,0 +1,113 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
import time
|
||||
from math import cos,sin
|
||||
|
||||
CLOCKS_PER_SEC = 1.0
|
||||
MHI_DURATION = 1
|
||||
MAX_TIME_DELTA = 0.5
|
||||
MIN_TIME_DELTA = 0.05
|
||||
N = 4
|
||||
buf = range(10)
|
||||
last = 0
|
||||
mhi = None # MHI
|
||||
orient = None # orientation
|
||||
mask = None # valid orientation mask
|
||||
segmask = None # motion segmentation map
|
||||
storage = None # temporary storage
|
||||
|
||||
def update_mhi( img, dst, diff_threshold ):
|
||||
global last
|
||||
global mhi
|
||||
global storage
|
||||
global mask
|
||||
global orient
|
||||
global segmask
|
||||
timestamp = time.clock()/CLOCKS_PER_SEC # get current time in seconds
|
||||
size = cvSize(img.width,img.height) # get current frame size
|
||||
idx1 = last
|
||||
if not mhi or mhi.width != size.width or mhi.height != size.height:
|
||||
for i in range( N ):
|
||||
buf[i] = cvCreateImage( size, IPL_DEPTH_8U, 1 )
|
||||
cvZero( buf[i] )
|
||||
mhi = cvCreateImage( size, IPL_DEPTH_32F, 1 )
|
||||
cvZero( mhi ) # clear MHI at the beginning
|
||||
orient = cvCreateImage( size, IPL_DEPTH_32F, 1 )
|
||||
segmask = cvCreateImage( size, IPL_DEPTH_32F, 1 )
|
||||
mask = cvCreateImage( size, IPL_DEPTH_8U, 1 )
|
||||
|
||||
cvCvtColor( img, buf[last], CV_BGR2GRAY ) # convert frame to grayscale
|
||||
idx2 = (last + 1) % N # index of (last - (N-1))th frame
|
||||
last = idx2
|
||||
silh = buf[idx2]
|
||||
cvAbsDiff( buf[idx1], buf[idx2], silh ) # get difference between frames
|
||||
cvThreshold( silh, silh, diff_threshold, 1, CV_THRESH_BINARY ) # and threshold it
|
||||
cvUpdateMotionHistory( silh, mhi, timestamp, MHI_DURATION ) # update MHI
|
||||
cvCvtScale( mhi, mask, 255./MHI_DURATION,
|
||||
(MHI_DURATION - timestamp)*255./MHI_DURATION )
|
||||
cvZero( dst )
|
||||
cvMerge( mask, None, None, None, dst )
|
||||
cvCalcMotionGradient( mhi, mask, orient, MAX_TIME_DELTA, MIN_TIME_DELTA, 3 )
|
||||
if( not storage ):
|
||||
storage = cvCreateMemStorage(0)
|
||||
else:
|
||||
cvClearMemStorage(storage)
|
||||
seq = cvSegmentMotion( mhi, segmask, storage, timestamp, MAX_TIME_DELTA )
|
||||
for i in range(-1, seq.total):
|
||||
if( i < 0 ): # case of the whole image
|
||||
comp_rect = cvRect( 0, 0, size.width, size.height )
|
||||
color = CV_RGB(255,255,255)
|
||||
magnitude = 100.
|
||||
else: # i-th motion component
|
||||
comp_rect = seq[i].rect
|
||||
if( comp_rect.width + comp_rect.height < 100 ): # reject very small components
|
||||
continue
|
||||
color = CV_RGB(255,0,0)
|
||||
magnitude = 30.
|
||||
silh_roi = cvGetSubRect(silh, comp_rect)
|
||||
mhi_roi = cvGetSubRect( mhi, comp_rect )
|
||||
orient_roi = cvGetSubRect( orient, comp_rect )
|
||||
mask_roi = cvGetSubRect( mask, comp_rect )
|
||||
angle = cvCalcGlobalOrientation( orient_roi, mask_roi, mhi_roi, timestamp, MHI_DURATION)
|
||||
angle = 360.0 - angle # adjust for images with top-left origin
|
||||
count = cvNorm( silh_roi, None, CV_L1, None ) # calculate number of points within silhouette ROI
|
||||
if( count < comp_rect.width * comp_rect.height * 0.05 ):
|
||||
continue
|
||||
center = cvPoint( (comp_rect.x + comp_rect.width/2),
|
||||
(comp_rect.y + comp_rect.height/2) )
|
||||
cvCircle( dst, center, cvRound(magnitude*1.2), color, 3, CV_AA, 0 )
|
||||
cvLine( dst, center, cvPoint( cvRound( center.x + magnitude*cos(angle*CV_PI/180)),
|
||||
cvRound( center.y - magnitude*sin(angle*CV_PI/180))), color, 3, CV_AA, 0 )
|
||||
|
||||
if __name__ == "__main__":
|
||||
motion = 0
|
||||
capture = 0
|
||||
|
||||
if len(sys.argv)==1:
|
||||
capture = cvCreateCameraCapture( 0 )
|
||||
elif len(sys.argv)==2 and sys.argv[1].isdigit():
|
||||
capture = cvCreateCameraCapture( int(sys.argv[1]) )
|
||||
elif len(sys.argv)==2:
|
||||
capture = cvCreateFileCapture( sys.argv[1] )
|
||||
|
||||
if not capture:
|
||||
print "Could not initialize capturing..."
|
||||
sys.exit(-1)
|
||||
|
||||
cvNamedWindow( "Motion", 1 )
|
||||
while True:
|
||||
image = cvQueryFrame( capture )
|
||||
if( image ):
|
||||
if( not motion ):
|
||||
motion = cvCreateImage( cvSize(image.width,image.height), 8, 3 )
|
||||
cvZero( motion )
|
||||
#motion.origin = image.origin
|
||||
update_mhi( image, motion, 30 )
|
||||
cvShowImage( "Motion", motion )
|
||||
if( cvWaitKey(10) != -1 ):
|
||||
break
|
||||
else:
|
||||
break
|
||||
cvDestroyWindow( "Motion" )
|
||||
Executable
+59
@@ -0,0 +1,59 @@
|
||||
#!/usr/bin/python
|
||||
import sys
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
image = [None, None]
|
||||
image0 = None
|
||||
image1 = None
|
||||
threshold1 = 255
|
||||
threshold2 = 30
|
||||
l = level = 4;
|
||||
block_size = 1000;
|
||||
filter = CV_GAUSSIAN_5x5;
|
||||
storage = None
|
||||
min_comp = CvConnectedComp()
|
||||
|
||||
def set_thresh1( val ):
|
||||
global threshold1
|
||||
threshold1 = val
|
||||
ON_SEGMENT()
|
||||
|
||||
def set_thresh2( val ):
|
||||
global threshold2
|
||||
threshold2 = val
|
||||
ON_SEGMENT()
|
||||
|
||||
def ON_SEGMENT():
|
||||
global storage
|
||||
global min_comp
|
||||
comp = cvPyrSegmentation(image0, image1, storage, level, threshold1+1, threshold2+1);
|
||||
cvShowImage("Segmentation", image1);
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = "../c/fruits.jpg";
|
||||
if len(sys.argv) == 2:
|
||||
filename = sys.argv[1]
|
||||
image[0] = cvLoadImage( filename, 1)
|
||||
if not image[0]:
|
||||
print "Error opening %s" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
cvNamedWindow("Source", 0);
|
||||
cvShowImage("Source", image[0]);
|
||||
cvNamedWindow("Segmentation", 0);
|
||||
storage = cvCreateMemStorage ( block_size );
|
||||
image[0].width &= -(1<<level);
|
||||
image[0].height &= -(1<<level);
|
||||
image0 = cvCloneImage( image[0] );
|
||||
image1 = cvCloneImage( image[0] );
|
||||
# segmentation of the color image
|
||||
l = 1;
|
||||
threshold1 =255;
|
||||
threshold2 =30;
|
||||
ON_SEGMENT();
|
||||
sthreshold1 = cvCreateTrackbar("Threshold1", "Segmentation", threshold1, 255, set_thresh1);
|
||||
sthreshold2 = cvCreateTrackbar("Threshold2", "Segmentation", threshold2, 255, set_thresh2);
|
||||
cvShowImage("Segmentation", image1);
|
||||
cvWaitKey(0);
|
||||
cvDestroyWindow("Segmentation");
|
||||
cvDestroyWindow("Source");
|
||||
Executable
+153
@@ -0,0 +1,153 @@
|
||||
#!/usr/bin/python
|
||||
#
|
||||
# The full "Square Detector" program.
|
||||
# It loads several images subsequentally and tries to find squares in
|
||||
# each image
|
||||
#
|
||||
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
from math import sqrt
|
||||
|
||||
thresh = 50;
|
||||
img = None;
|
||||
img0 = None;
|
||||
storage = None;
|
||||
wndname = "Square Detection Demo";
|
||||
|
||||
def angle( pt1, pt2, pt0 ):
|
||||
dx1 = pt1.x - pt0.x;
|
||||
dy1 = pt1.y - pt0.y;
|
||||
dx2 = pt2.x - pt0.x;
|
||||
dy2 = pt2.y - pt0.y;
|
||||
return (dx1*dx2 + dy1*dy2)/sqrt((dx1*dx1 + dy1*dy1)*(dx2*dx2 + dy2*dy2) + 1e-10);
|
||||
|
||||
def findSquares4( img, storage ):
|
||||
N = 11;
|
||||
sz = cvSize( img.width & -2, img.height & -2 );
|
||||
timg = cvCloneImage( img ); # make a copy of input image
|
||||
gray = cvCreateImage( sz, 8, 1 );
|
||||
pyr = cvCreateImage( cvSize(sz.width/2, sz.height/2), 8, 3 );
|
||||
# create empty sequence that will contain points -
|
||||
# 4 points per square (the square's vertices)
|
||||
squares = cvCreateSeq( 0, sizeof_CvSeq, sizeof_CvPoint, storage );
|
||||
squares = CvSeq_CvPoint.cast( squares )
|
||||
|
||||
# select the maximum ROI in the image
|
||||
# with the width and height divisible by 2
|
||||
subimage = cvGetSubRect( timg, cvRect( 0, 0, sz.width, sz.height ))
|
||||
|
||||
# down-scale and upscale the image to filter out the noise
|
||||
cvPyrDown( subimage, pyr, 7 );
|
||||
cvPyrUp( pyr, subimage, 7 );
|
||||
tgray = cvCreateImage( sz, 8, 1 );
|
||||
# find squares in every color plane of the image
|
||||
for c in range(3):
|
||||
# extract the c-th color plane
|
||||
channels = [None, None, None]
|
||||
channels[c] = tgray
|
||||
cvSplit( subimage, channels[0], channels[1], channels[2], None )
|
||||
for l in range(N):
|
||||
# hack: use Canny instead of zero threshold level.
|
||||
# Canny helps to catch squares with gradient shading
|
||||
if( l == 0 ):
|
||||
# apply Canny. Take the upper threshold from slider
|
||||
# and set the lower to 0 (which forces edges merging)
|
||||
cvCanny( tgray, gray, 0, thresh, 5 );
|
||||
# dilate canny output to remove potential
|
||||
# holes between edge segments
|
||||
cvDilate( gray, gray, None, 1 );
|
||||
else:
|
||||
# apply threshold if l!=0:
|
||||
# tgray(x,y) = gray(x,y) < (l+1)*255/N ? 255 : 0
|
||||
cvThreshold( tgray, gray, (l+1)*255/N, 255, CV_THRESH_BINARY );
|
||||
|
||||
# find contours and store them all as a list
|
||||
count, contours = cvFindContours( gray, storage, sizeof_CvContour,
|
||||
CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0) );
|
||||
|
||||
if not contours:
|
||||
continue
|
||||
|
||||
# test each contour
|
||||
for contour in contours.hrange():
|
||||
# approximate contour with accuracy proportional
|
||||
# to the contour perimeter
|
||||
result = cvApproxPoly( contour, sizeof_CvContour, storage,
|
||||
CV_POLY_APPROX_DP, cvContourPerimeter(contours)*0.02, 0 );
|
||||
# square contours should have 4 vertices after approximation
|
||||
# relatively large area (to filter out noisy contours)
|
||||
# and be convex.
|
||||
# Note: absolute value of an area is used because
|
||||
# area may be positive or negative - in accordance with the
|
||||
# contour orientation
|
||||
if( result.total == 4 and
|
||||
abs(cvContourArea(result)) > 1000 and
|
||||
cvCheckContourConvexity(result) ):
|
||||
s = 0;
|
||||
for i in range(5):
|
||||
# find minimum angle between joint
|
||||
# edges (maximum of cosine)
|
||||
if( i >= 2 ):
|
||||
t = abs(angle( result[i], result[i-2], result[i-1]))
|
||||
if s<t:
|
||||
s=t
|
||||
# if cosines of all angles are small
|
||||
# (all angles are ~90 degree) then write quandrange
|
||||
# vertices to resultant sequence
|
||||
if( s < 0.3 ):
|
||||
for i in range(4):
|
||||
squares.append( result[i] )
|
||||
|
||||
return squares;
|
||||
|
||||
# the function draws all the squares in the image
|
||||
def drawSquares( img, squares ):
|
||||
cpy = cvCloneImage( img );
|
||||
# read 4 sequence elements at a time (all vertices of a square)
|
||||
i=0
|
||||
while i<squares.total:
|
||||
pt = []
|
||||
# read 4 vertices
|
||||
pt.append( squares[i] )
|
||||
pt.append( squares[i+1] )
|
||||
pt.append( squares[i+2] )
|
||||
pt.append( squares[i+3] )
|
||||
|
||||
# draw the square as a closed polyline
|
||||
cvPolyLine( cpy, [pt], 1, CV_RGB(0,255,0), 3, CV_AA, 0 );
|
||||
i+=4
|
||||
|
||||
# show the resultant image
|
||||
cvShowImage( wndname, cpy );
|
||||
|
||||
def on_trackbar( a ):
|
||||
if( img ):
|
||||
drawSquares( img, findSquares4( img, storage ) );
|
||||
|
||||
names = ["../c/pic1.png", "../c/pic2.png", "../c/pic3.png",
|
||||
"../c/pic4.png", "../c/pic5.png", "../c/pic6.png" ];
|
||||
|
||||
if __name__ == "__main__":
|
||||
# create memory storage that will contain all the dynamic data
|
||||
storage = cvCreateMemStorage(0);
|
||||
for name in names:
|
||||
img0 = cvLoadImage( name, 1 );
|
||||
if not img0:
|
||||
print "Couldn't load %s" % name
|
||||
continue;
|
||||
img = cvCloneImage( img0 );
|
||||
# create window and a trackbar (slider) with parent "image" and set callback
|
||||
# (the slider regulates upper threshold, passed to Canny edge detector)
|
||||
cvNamedWindow( wndname, 1 );
|
||||
cvCreateTrackbar( "canny thresh", wndname, thresh, 1000, on_trackbar );
|
||||
# force the image processing
|
||||
on_trackbar(0);
|
||||
# wait for key.
|
||||
# Also the function cvWaitKey takes care of event processing
|
||||
c = cvWaitKey(0);
|
||||
# clear memory storage - reset free space position
|
||||
cvClearMemStorage( storage );
|
||||
if( c == '\x1b' ):
|
||||
break;
|
||||
cvDestroyWindow( wndname );
|
||||
Executable
+111
@@ -0,0 +1,111 @@
|
||||
#!/usr/bin/python
|
||||
from opencv.cv import *
|
||||
from opencv.highgui import *
|
||||
import sys
|
||||
|
||||
marker_mask = None;
|
||||
markers = None;
|
||||
img0 = None
|
||||
img = None
|
||||
img_gray = None
|
||||
wshed = None
|
||||
prev_pt = cvPoint(-1,-1)
|
||||
|
||||
def on_mouse( event, x, y, flags, param ):
|
||||
global prev_pt
|
||||
if( not img ):
|
||||
return;
|
||||
if( event == CV_EVENT_LBUTTONUP or not (flags & CV_EVENT_FLAG_LBUTTON) ):
|
||||
prev_pt = cvPoint(-1,-1);
|
||||
elif( event == CV_EVENT_LBUTTONDOWN ):
|
||||
prev_pt = cvPoint(x,y);
|
||||
elif( event == CV_EVENT_MOUSEMOVE and (flags & CV_EVENT_FLAG_LBUTTON) ):
|
||||
pt = cvPoint(x,y);
|
||||
if( prev_pt.x < 0 ):
|
||||
prev_pt = pt;
|
||||
cvLine( marker_mask, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
|
||||
cvLine( img, prev_pt, pt, cvScalarAll(255), 5, 8, 0 );
|
||||
prev_pt = pt;
|
||||
cvShowImage( "image", img );
|
||||
|
||||
if __name__ == "__main__":
|
||||
filename = "../c/fruits.jpg"
|
||||
if len(sys.argv)>1:
|
||||
filename = sys.argv[1]
|
||||
|
||||
rng = cvRNG(-1);
|
||||
img0 = cvLoadImage(filename,1)
|
||||
if not img0:
|
||||
print "Error opening image '%s'" % filename
|
||||
sys.exit(-1)
|
||||
|
||||
print "Hot keys:"
|
||||
print "\tESC - quit the program"
|
||||
print "\tr - restore the original image"
|
||||
print "\tw - run watershed algorithm"
|
||||
print "\t (before that, roughly outline several markers on the image)"
|
||||
|
||||
cvNamedWindow( "image", 1 );
|
||||
cvNamedWindow( "watershed transform", 1 );
|
||||
|
||||
img = cvCloneImage( img0 );
|
||||
img_gray = cvCloneImage( img0 );
|
||||
wshed = cvCloneImage( img0 );
|
||||
marker_mask = cvCreateImage( cvGetSize(img), 8, 1 );
|
||||
markers = cvCreateImage( cvGetSize(img), IPL_DEPTH_32S, 1 );
|
||||
|
||||
cvCvtColor( img, marker_mask, CV_BGR2GRAY );
|
||||
cvCvtColor( marker_mask, img_gray, CV_GRAY2BGR );
|
||||
|
||||
cvZero( marker_mask );
|
||||
cvZero( wshed );
|
||||
|
||||
cvShowImage( "image", img );
|
||||
cvShowImage( "watershed transform", wshed );
|
||||
|
||||
cvSetMouseCallback( "image", on_mouse, None );
|
||||
while True:
|
||||
c = cvWaitKey(0);
|
||||
if c=='\x1b':
|
||||
break;
|
||||
if c == 'r':
|
||||
cvZero( marker_mask );
|
||||
cvCopy( img0, img );
|
||||
cvShowImage( "image", img );
|
||||
if c == 'w':
|
||||
storage = cvCreateMemStorage(0);
|
||||
comp_count = 0;
|
||||
#cvSaveImage( "wshed_mask.png", marker_mask );
|
||||
#marker_mask = cvLoadImage( "wshed_mask.png", 0 );
|
||||
nb_cont, contours = cvFindContours( marker_mask, storage, sizeof_CvContour,
|
||||
CV_RETR_CCOMP, CV_CHAIN_APPROX_SIMPLE );
|
||||
cvZero( markers );
|
||||
while contours:
|
||||
cvDrawContours( markers, contours, cvScalarAll(comp_count+1),
|
||||
cvScalarAll(comp_count+1), -1, -1, 8, cvPoint(0,0) );
|
||||
contours=contours.h_next
|
||||
comp_count+=1
|
||||
color_tab = cvCreateMat( comp_count, 1, CV_8UC3 );
|
||||
for i in range(comp_count):
|
||||
color_tab[i] = cvScalar( cvRandInt(rng)%180 + 50,
|
||||
cvRandInt(rng)%180 + 50,
|
||||
cvRandInt(rng)%180 + 50 );
|
||||
t = cvGetTickCount();
|
||||
cvWatershed( img0, markers );
|
||||
t = cvGetTickCount() - t;
|
||||
#print "exec time = %f" % t/(cvGetTickFrequency()*1000.)
|
||||
|
||||
cvSet( wshed, cvScalarAll(255) );
|
||||
|
||||
# paint the watershed image
|
||||
for j in range(markers.height):
|
||||
for i in range(markers.width):
|
||||
idx = markers[j,i]
|
||||
if idx==-1:
|
||||
continue
|
||||
idx = idx-1
|
||||
wshed[j,i] = color_tab[idx,0]
|
||||
|
||||
cvAddWeighted( wshed, 0.5, img_gray, 0.5, 0, wshed );
|
||||
cvShowImage( "watershed transform", wshed );
|
||||
cvWaitKey();
|
||||
Reference in New Issue
Block a user