Merge branch 'master' of git://github.com/sccolbert/scikits.image into chris

This commit is contained in:
Stefan van der Walt
2010-06-24 17:38:49 -07:00
6 changed files with 441 additions and 9 deletions
@@ -248,6 +248,7 @@ cdef void rgb_2_hsv(float* RGB, float* HSV) nogil:
else:
pass
if R < G:
MIN = R
MAX = G
+3 -2
View File
@@ -66,7 +66,7 @@ class IntelligentSlider(QWidget):
return self.slider.value() * self.a + self.b
class MixerPanel(QWidget):
class MixerPanel(QtGui.QFrame):
'''A color mixer to hook up to an image.
You pass the image you the panel to operate on
and it operates on that image in place. You also
@@ -74,7 +74,8 @@ class MixerPanel(QWidget):
This callback is called every time the mixer modifies
your image.'''
def __init__(self, img):
QWidget.__init__(self)
QtGui.QFrame.__init__(self)
#self.setFrameStyle(QtGui.QFrame.Box|QtGui.QFrame.Sunken)
self.img = img
self.mixer = ColorMixer(self.img)
+6 -3
View File
@@ -1,6 +1,6 @@
import numpy as np
from PyQt4.QtGui import QWidget, QPainter, QGridLayout, QColor
from PyQt4.QtGui import QWidget, QPainter, QGridLayout, QColor, QFrame
from util import histograms
@@ -103,7 +103,7 @@ class ColorHistogram(QWidget):
self.repaint()
class QuadHistogram(QWidget):
class QuadHistogram(QFrame):
'''A class which uses ColorHistogram to draw
the 4 histograms of an image. R, G, B, and Value.
@@ -113,14 +113,17 @@ class QuadHistogram(QWidget):
'''
def __init__(self, img, layout='vertical', order=['R', 'G', 'B', 'V']):
QWidget.__init__(self)
QFrame.__init__(self)
r, g, b, v = histograms(img, 100)
self.r_hist = ColorHistogram(r, (255, 0, 0))
self.g_hist = ColorHistogram(g, (0, 255, 0))
self.b_hist = ColorHistogram(b, (0, 0, 255))
self.v_hist = ColorHistogram(v, (0, 0, 0))
self.setFrameStyle(QFrame.StyledPanel|QFrame.Sunken)
self.layout = QGridLayout(self)
self.layout.setMargin(0)
order_map = {'R': self.r_hist, 'G': self.g_hist, 'B': self.b_hist,
'V': self.v_hist}
+13 -4
View File
@@ -66,9 +66,11 @@ class ImageLabel(QLabel):
self.setPixmap(pm)
class RGBHSVDisplay(QWidget):
class RGBHSVDisplay(QFrame):
def __init__(self):
QWidget.__init__(self)
QFrame.__init__(self)
self.setFrameStyle(QtGui.QFrame.Box|QtGui.QFrame.Sunken)
self.posx_label = QLabel('X-pos:')
self.posx_value = QLabel()
self.posy_label = QLabel('Y-pos:')
@@ -129,8 +131,15 @@ class SciviImageWindow(QMainWindow):
self.setCentralWidget(self.main_widget)
self.label = ImageLabel(self, arr)
self.layout.addWidget(self.label, 0, 0)
self.layout.addLayout
self.label_container = QFrame()
self.label_container.setFrameShape(QtGui.QFrame.StyledPanel|QtGui.QFrame.Sunken)
self.label_container.setLineWidth(1)
self.label_container.layout = QtGui.QGridLayout(self.label_container)
self.label_container.layout.setMargin(0)
self.label_container.layout.addWidget(self.label, 0, 0)
self.layout.addWidget(self.label_container, 0, 0)
self.mgr.add_window(self)
self.main_widget.show()
+10
View File
@@ -201,5 +201,15 @@ CV_64FC2 = _CV_MAKETYPE(CV_64F,2)
CV_64FC3 = _CV_MAKETYPE(CV_64F,3)
CV_64FC4 = _CV_MAKETYPE(CV_64F,4)
#-------------------------------------------------------------------------------
# Template Matching
#-------------------------------------------------------------------------------
CV_TM_SQDIFF = 0
CV_TM_SQDIFF_NORMED = 1
CV_TM_CCORR = 2
CV_TM_CCORR_NORMED = 3
CV_TM_CCOEFF = 4
CV_TM_CCOEFF_NORMED = 5
+408
View File
@@ -261,6 +261,11 @@ ctypedef void (*cvPyrUpPtr)(IplImage*, IplImage*, int)
cdef cvPyrUpPtr c_cvPyrUp
c_cvPyrUp = (<cvPyrUpPtr*><size_t>ctypes.addressof(cv.cvPyrUp))[0]
# cvWatershed
ctypedef void (*cvWatershedPtr)(IplImage*, IplImage*)
cdef cvWatershedPtr c_cvWatershed
c_cvWatershed = (<cvWatershedPtr*><size_t>ctypes.addressof(cv.cvWatershed))[0]
# cvCalibrateCamera2
ctypedef void (*cvCalibrateCamera2Ptr)(CvMat*, CvMat*, CvMat*,
CvSize, CvMat*, CvMat*, CvMat*, CvMat*, int)
@@ -280,6 +285,14 @@ cdef cvFindChessboardCornersPtr c_cvFindChessboardCorners
c_cvFindChessboardCorners = (<cvFindChessboardCornersPtr*><size_t>
ctypes.addressof(cv.cvFindChessboardCorners))[0]
# cvFindExtrinsicCameraParams2
ctypedef void (*cvFindExtrinsicCameraParams2Ptr)(CvMat*, CvMat*, CvMat*, CvMat*,
CvMat*, CvMat*, int)
cdef cvFindExtrinsicCameraParams2Ptr c_cvFindExtrinsicCameraParams2
c_cvFindExtrinsicCameraParams2 = \
(<cvFindExtrinsicCameraParams2Ptr*><size_t>
ctypes.addressof(cv.cvFindExtrinsicCameraParams2))[0]
# cvDrawChessboardCorners
ctypedef void (*cvDrawChessboardCornersPtr)(IplImage*, CvSize, CvPoint2D32f*,
int, int)
@@ -287,6 +300,18 @@ cdef cvDrawChessboardCornersPtr c_cvDrawChessboardCorners
c_cvDrawChessboardCorners = (<cvDrawChessboardCornersPtr*><size_t>
ctypes.addressof(cv.cvDrawChessboardCorners))[0]
# cvFloodFill
ctypedef void (*cvFloodFillPtr)(IplImage*, CvPoint, CvScalar, CvScalar,
CvScalar, void*, int, IplImage*)
cdef cvFloodFillPtr c_cvFloodFill
c_cvFloodFill = (<cvFloodFillPtr*><size_t>ctypes.addressof(cv.cvFloodFill))[0]
# cvMatchTemplate
ctypedef void (*cvMatchTemplatePtr)(IplImage*, IplImage*, IplImage*, int)
cdef cvMatchTemplatePtr c_cvMatchTemplate
c_cvMatchTemplate = (<cvMatchTemplatePtr*><size_t>
ctypes.addressof(cv.cvMatchTemplate))[0]
#-------------------------------------------------------------------------------
# Function Implementations
#-------------------------------------------------------------------------------
@@ -2070,6 +2095,54 @@ def cvPyrUp(np.ndarray src):
return out
#------------
# cvWatershed
#------------
@cvdoc(package='cv', group='image', doc=\
'''cvWatershed(src, markers)
Performs watershed segmentation.
Parameters
----------
src : ndarray, 3D, dtype=uint8
The source image.
markers : ndarray, 2D, dtype=int32
The markers identifying the regions of interest.
Marker values should be non-zero.
This array should have the same width and height as src.
Returns
-------
None : None
The markers array is modified in place. The results of which
identify the segmented regions of the image.''')
def cvWatershed(src, markers):
validate_array(src)
validate_array(markers)
assert_ndims(src, [3])
assert_dtype(src, [UINT8])
assert_ndims(markers, [2])
assert_dtype(markers, [INT32])
#assert src.shape[:2] == markers.shape[:2], \
# 'The src and markers array must have same width and height'
cdef IplImage srcimg
cdef IplImage markersimg
populate_iplimage(src, &srcimg)
populate_iplimage(markers, &markersimg)
c_cvWatershed(&srcimg, &markersimg)
return None
#-------------------
# cvCalibrateCamera2
#-------------------
@@ -2281,6 +2354,102 @@ def cvFindChessboardCorners(np.ndarray src, pattern_size,
return out[:ncorners_found]
#-----------------------------
# cvFindExtrinsicCameraParams2
#-----------------------------
@cvdoc(package='cv', group='calibration', doc=\
'''cvFindExtrinsicCameraParams2(object_points, image_points, intrinsic_matrix,
distortion_coeffs)
Calculates the extrinsic camera parameters given a set of 3D points, their
2D locations in the image, and the camera instrinsics matrix and distortion
coefficients.
i.e. given this information, it calculates the offset and rotation of the
camera from the chessboard origin.
Parameters
----------
object_points: ndarray, nx3
The 3D coordinates of the chessboard corners.
image_points: ndarray, nx2
The 2D image coordinates of the object_points
intrinsic_matrix: ndarray, 3x3, dtype=float64
The 2D camera intrinsics matrix that is the result of camera calibration
distortion_coeffs: ndarray, 5-vector, dtype=float64
The 5 distortion coefficients that are the result of camera calibration
Returns
-------
(rvec, tvec): ndarray 3-vector dtype=float64, ndarray 3-vector dtype=float64
rvec - the rotation vector representing the rotation of the camera
relative to the chessboard. The direction of the vector represents the
axis of rotation and its magnitude the amount of rotation.
tvec - the translation vector representing the offset of the camera
relative to the chessboard origin.''')
def cvFindExtrinsicCameraParams2(object_points, image_points, intrinsic_matrix,
distortion_coeffs):
validate_array(object_points)
validate_array(image_points)
validate_array(intrinsic_matrix)
assert_ndims(object_points, [2])
assert_dtype(object_points, [FLOAT32, FLOAT64])
assert object_points.shape[1] == 3, 'object_points should be nx3'
assert_ndims(image_points, [2])
assert_dtype(image_points, [FLOAT32, FLOAT64])
assert image_points.shape[1] == 2, 'image_points should be nx2'
assert_dtype(intrinsic_matrix, [FLOAT64])
assert intrinsic_matrix.shape == (3, 3), 'instrinsics should be 3x3'
assert_dtype(distortion_coeffs, [FLOAT64])
assert distortion_coeffs.shape == (5,), 'distortions should be 5-vector'
# allocate the numpy return arrays
cdef np.npy_intp shape[1]
shape[0] = 3
cdef np.ndarray rvec = new_array(1, shape, FLOAT64)
cdef np.ndarray tvec = new_array(1, shape, FLOAT64)
# allocate the cv images
cdef IplImage obj_img
cdef IplImage img_img
cdef IplImage intr_img
cdef IplImage dist_img
cdef IplImage rot_img
cdef IplImage tran_img
populate_iplimage(object_points, &obj_img)
populate_iplimage(image_points, &img_img)
populate_iplimage(intrinsic_matrix, &intr_img)
populate_iplimage(distortion_coeffs, &dist_img)
populate_iplimage(rvec, &rot_img)
populate_iplimage(tvec, &tran_img)
# allocate the cv mats
cdef CvMat* cvobj = cvmat_ptr_from_iplimage(&obj_img)
cdef CvMat* cvimg = cvmat_ptr_from_iplimage(&img_img)
cdef CvMat* cvint = cvmat_ptr_from_iplimage(&intr_img)
cdef CvMat* cvdis = cvmat_ptr_from_iplimage(&dist_img)
cdef CvMat* cvrot = cvmat_ptr_from_iplimage(&rot_img)
cdef CvMat* cvtrn = cvmat_ptr_from_iplimage(&tran_img)
# the last argument is new to OpenCV 2.0 and tells it NOT to use
# an extrinsics guess
c_cvFindExtrinsicCameraParams2(cvobj, cvimg, cvint, cvdis, cvrot, cvtrn, 0)
PyMem_Free(cvobj)
PyMem_Free(cvimg)
PyMem_Free(cvint)
PyMem_Free(cvdis)
PyMem_Free(cvrot)
PyMem_Free(cvtrn)
return (rvec, tvec)
#------------------------
# cvFindChessboardCorners
#------------------------
@@ -2354,3 +2523,242 @@ def cvDrawChessboardCorners(np.ndarray src, pattern_size, np.ndarray corners,
return out
#------------
# cvFloodFill
#------------
@cvdoc(package='cv', group='image', doc=\
'''cvFloodFill(np.ndarray src, seed_point, new_val, low_diff, high_diff,
mask=None, connect_diag=False, mask_only=False,
mask_fillval=None, fixed_range=False)
Fills a connected component with the given color.
Parameters
----------
src : ndarray, ndims=[2, 3], dtypes[uint8, float32]
The source image
seed_point : (x, y) int tuple
The starting point of the fill in image pixel coordinates.
new_val : scalar double or 3-tuple (R, G, B) doubles
The color value of the repainted area. If a scalar, the RGB values
are all set equal to the scalar.
low_diff : scalar double or 3-tuple (R, G, B) doubles
Maximal lower brightness/color difference between the currently
observed pixel and one of its neighbors belonging to the component,
or a seed pixel being added to the component. Must be positive.
high_diff : scalar double or 3-tuple (R, G, B) doubles
Maximal upper brightness/color difference between the currently
observed pixel and one of its neighbors belonging to the component,
or a seed pixel being added to the component. Must be positive.
mask : ndarray 2d, dtype=uint8 or None
The mask in which to draw the results and/or use as a mask.
See the opencv documentation for more details.
If not None, the mask shape must be 2 pixels wider and taller than src.
connect_diag : bool
If True, implies connectivity across the diagonals in addition to
the standard horizontal and vertical directions.
mask_only : bool
If True, fill the mask instead of the image.
Mask must not be None
mask_fillval : int 0 - 255 or None
The value to fill the mask if mask is not None.
If None, defaults to 1
fixed_range : bool
If True, fills relative to seed value, else, fills relative to
neighbors value.
Returns
-------
None : None
This is an in-place operation which draws into src and/or image depending
on the flags set in the input arguments''')
def cvFloodFill(np.ndarray src, seed_point, new_val, low_diff, high_diff,
mask=None, connect_diag=False, mask_only=False,
mask_fillval=None, fixed_range=False):
validate_array(src)
assert_ndims(src, [2, 3])
assert_dtype(src, [UINT8, FLOAT32])
# src
cdef IplImage srcimg
populate_iplimage(src, &srcimg)
# seed_point
if len(seed_point) != 2:
raise ValueError('seed_point should be an (x, y) tuple of ints')
cdef CvPoint cv_seed_point
cdef int x = <int>seed_point[0]
cdef int y = <int>seed_point[1]
cdef int xmax = <int>src.shape[1]
cdef int ymax = <int>src.shape[0]
if x < 0 or x > xmax or y < 0 or y > ymax:
raise ValueError('seed_point must be image pixel coordinates')
cv_seed_point.x = x
cv_seed_point.y = y
# loop counter
cdef int i
cdef double temp
# new_val
cdef CvScalar cv_new_val
if hasattr(new_val, '__len__'):
if len(new_val) != 3:
raise ValueError('If not a scalar, new_val must be 3 tuple')
for i in range(3):
cv_new_val.val[i] = <double>new_val[i]
else:
temp = <double>new_val
for i in range(3):
cv_new_val.val[i] = temp
# low_diff
cdef CvScalar cv_low_diff
if hasattr(low_diff, '__len__'):
if len(low_diff) != 3:
raise ValueError('If not a scalar, low_diff must be 3 tuple')
for i in range(3):
cv_low_diff.val[i] = <double>low_diff[i]
else:
temp = <double>low_diff
for i in range(3):
cv_low_diff.val[i] = temp
# high_diff
cdef CvScalar cv_high_diff
if hasattr(high_diff, '__len__'):
if len(high_diff) != 3:
raise ValueError('If not a scalar, high_diff must be 3 tuple')
for i in range(3):
cv_high_diff.val[i] = <double>high_diff[i]
else:
temp = <double>high_diff
for i in range(3):
cv_high_diff.val[i] = temp
# mask
cdef IplImage maskimg
cdef IplImage* maskimgptr = NULL
if mask is not None:
validate_array(mask)
assert_ndims(mask, [2])
assert_dtype(mask, [UINT8])
if mask.shape[0] != (src.shape[0] + 2) or \
mask.shape[1] != (src.shape[1] + 2):
raise ValueError('mask must be 2 pixels wider and taller than src.')
populate_iplimage(mask, &maskimg)
maskimgptr = &maskimg
# flags
cdef int flags
# connect_diag
cdef int cv_connect_diag = 4
if connect_diag:
cv_connect_diag = 8
# mask_only
cdef int cv_mask_only = 0
if mask_only:
if mask is None:
raise ValueError('If mask_only==True, mask must not be None')
cv_mask_only = (1 << 17)
# mask_fillval
cdef int cv_mask_fillval = (1 << 8)
if mask_fillval:
if mask_fillval < 0 or mask_fillval > 255:
raise ValueError('mask_fillval must be in range 0-255')
cv_mask_fillval = ((<int>mask_fillval) << 8)
# fixed_range
cdef int cv_fixed_range = 0
if fixed_range:
cv_fixed_range = (1 << 16)
flags = cv_connect_diag | cv_mask_only | cv_mask_fillval | cv_fixed_range
c_cvFloodFill(&srcimg, cv_seed_point, cv_new_val, cv_low_diff, cv_high_diff,
NULL, flags, maskimgptr)
return None
#----------------
# cvMatchTemplate
#----------------
@cvdoc(package='cv', group='image', doc=\
'''cvMatchTemplate(src, template, method)
Compares a template against overlapped image regions and returns a match array
dependent on the match method requested.
Parameters
----------
src : ndarray, ndims=[2, 3], dtype=[uint8, float32]
The source image.
template : ndarray, ndim=src.ndim, dtype=src.dtype
The template to match in the source.
method : int
The method to use for matching.
One of:
CV_TM_SQDIFF
CV_TM_SQDIFF_NORMED
CV_TM_CCORR
CV_TM_CCORR_NORMED
CV_TM_CCOEFF
CV_TM_CCOEFF_NORMED
Returns
-------
out : ndarray, 2d, dtype=float3d
The results of the template matching.
The size of this array (H - h + 1) x (W - w + 1)
where (H, W) is (Height, Width) of src and (h, w) is
(height, width) of template.
Notes
-----
After the function finishes the comparison, the best matches can be found
as global minimums (CV_TM_SQDIFF) or maximums (CV_TM_CCORR and CV_TM_CCOEFF)
using the appropriate numpy functions. In the case of a color image,
template summation in the numerator and each sum in the denominator
is done over all of the channels (and separate mean values are used for each
channel).''')
def cvMatchTemplate(np.ndarray src, np.ndarray template, int method):
validate_array(src)
validate_array(template)
assert_ndims(src, [2, 3])
assert_dtype(src, [UINT8, FLOAT32])
assert_ndims(template, [src.ndim])
assert_dtype(template, [src.dtype])
if method not in [CV_TM_SQDIFF_NORMED, CV_TM_CCORR, CV_TM_CCORR_NORMED,
CV_TM_CCOEFF, CV_TM_CCOEFF_NORMED]:
raise ValueError('Unknown method type')
if src.shape[0] <= template.shape[0] or src.shape[1] <= template.shape[1]:
raise ValueError('template must be smaller than source image')
cdef np.npy_intp outshape[2]
outshape[0] = <np.npy_intp>(src.shape[0] - template.shape[0] + 1)
outshape[1] = <np.npy_intp>(src.shape[1] - template.shape[1] + 1)
cdef np.ndarray out = new_array(2, outshape, FLOAT32)
cdef IplImage srcimg
cdef IplImage templateimg
cdef IplImage outimg
populate_iplimage(src, &srcimg)
populate_iplimage(template, &templateimg)
populate_iplimage(out, &outimg)
c_cvMatchTemplate(&srcimg, &templateimg, &outimg, method)
return out