'**SUMMARY**
Consider you want to crop a image with the following dimension::
(x,y)
|              |h
w      (x1,y1)
Crop attempts to use the x and y position variables and the w and h width
and height variables to crop the image. When centered is false, x and y
define the top and left of the cropped rectangle. When centered is true
the function uses x and y as the centroid of the cropped region.
You can also pass a feature into crop and have it automatically return
the cropped image within the bounding outside area of that feature
Or parameters can be in the form of a
- tuple or list : (x,y,w,h) or [x,y,w,h]
- two points : (x,y),(x1,y1) or [(x,y),(x1,y1)]
**PARAMETERS**
* *x* - An integer or feature.
- If it is a feature we crop to the features dimensions.
- This can be either the top left corner of the image or the center cooridnate of the the crop region.
- or in the form of tuple/list. i,e (x,y,w,h) or [x,y,w,h]
- Otherwise in two point form. i,e [(x,y),(x1,y1)] or (x,y)
* *y* - The y coordinate of the center, or top left corner  of the crop region.
- Otherwise in two point form. i,e (x1,y1)
* *w* - Int - the width of the cropped region in pixels.
* *h* - Int - the height of the cropped region in pixels.
* *centered*  - Boolean - if True we treat the crop region as being the center
coordinate and a width and height. If false we treat it as the top left corner of the crop region.
* *smart* - Will make sure you don\'t try and crop outside the image size, so if your image is 100x100 and you tried a crop like img.crop(50,50,100,100), it will autoscale the crop to the max width.
**RETURNS**
A SimpleCV Image cropped to the specified width and height.
**EXAMPLE**
>>> img = Image(\'lenna\')
>>> img.crop(50,40,128,128).show()
>>> img.crop((50,40,128,128)).show() #roi
>>> img.crop([50,40,128,128]) #roi
>>> img.crop((50,40),(178,168)) # two point form
>>> img.crop([(50,40),(178,168)]) # two point form
>>> img.crop([x1,x2,x3,x4,x5],[y1,y1,y3,y4,y5]) # list of x\'s and y\'s
>>> img.crop([(x,y),(x,y),(x,y),(x,y),(x,y)] # list of (x,y)
>>> img.crop(x,y,100,100, smart=True)
**SEE ALSO**
:py:meth:`embiggen`
:py:meth:`regionSelect`'

def crop(self, x, y=None, w=None, h=None, centered=False, smart=False):

    if smart:
        if (x > self.width):
            x = self.width
        elif (x < 0):
            x = 0
        elif (y > self.height):
            y = self.height
        elif (y < 0):
            y = 0
        elif ((x + w) > self.width):
            w = (self.width - x)
        elif ((y + h) > self.height):
            h = (self.height - y)
    if isinstance(x, np.ndarray):
        x = x.tolist()
    if isinstance(y, np.ndarray):
        y = y.tolist()
    if isinstance(x, Feature):
        theFeature = x
        x = theFeature.points[0][0]
        y = theFeature.points[0][1]
        w = theFeature.width()
        h = theFeature.height()
    elif (isinstance(x, (tuple, list)) and (len(x) == 4) and isinstance(x[0], (int, long, float)) and (y == None) and (w == None) and (h == None)):
        (x, y, w, h) = x
    elif (isinstance(x, (list, tuple)) and isinstance(x[0], (list, tuple)) and ((len(x) == 4) and (len(x[0]) == 2)) and (y == None) and (w == None) and (h == None)):
        if ((len(x[0]) == 2) and (len(x[1]) == 2) and (len(x[2]) == 2) and (len(x[3]) == 2)):
            xmax = np.max([x[0][0], x[1][0], x[2][0], x[3][0]])
            ymax = np.max([x[0][1], x[1][1], x[2][1], x[3][1]])
            xmin = np.min([x[0][0], x[1][0], x[2][0], x[3][0]])
            ymin = np.min([x[0][1], x[1][1], x[2][1], x[3][1]])
            x = xmin
            y = ymin
            w = (xmax - xmin)
            h = (ymax - ymin)
        else:
            logger.warning('x    should    be    in    the    form        ((x,y),(x1,y1),(x2,y2),(x3,y3))')
            return None
    elif (isinstance(x, (tuple, list)) and isinstance(y, (tuple, list)) and (len(x) > 4) and (len(y) > 4)):
        if (isinstance(x[0], (int, long, float)) and isinstance(y[0], (int, long, float))):
            xmax = np.max(x)
            ymax = np.max(y)
            xmin = np.min(x)
            ymin = np.min(y)
            x = xmin
            y = ymin
            w = (xmax - xmin)
            h = (ymax - ymin)
        else:
            logger.warning('x    should    be    in    the    form    x    =    [1,2,3,4,5]    y    =[0,2,4,6,8]')
            return None
    elif (isinstance(x, (list, tuple)) and (len(x) > 4) and (len(x[0]) == 2) and (y == None) and (w == None) and (h == None)):
        if isinstance(x[0][0], (int, long, float)):
            xs = [pt[0] for pt in x]
            ys = [pt[1] for pt in x]
            xmax = np.max(xs)
            ymax = np.max(ys)
            xmin = np.min(xs)
            ymin = np.min(ys)
            x = xmin
            y = ymin
            w = (xmax - xmin)
            h = (ymax - ymin)
        else:
            logger.warning('x    should    be    in    the    form    [(x,y),(x,y),(x,y),(x,y),(x,y),(x,y)]')
            return None
    elif (isinstance(x, (list, tuple)) and (len(x) == 2) and isinstance(x[0], (list, tuple)) and isinstance(x[1], (list, tuple)) and (y == None) and (w == None) and (h == None)):
        if ((len(x[0]) == 2) and (len(x[1]) == 2)):
            xt = np.min([x[0][0], x[1][0]])
            yt = np.min([x[0][0], x[1][0]])
            w = np.abs((x[0][0] - x[1][0]))
            h = np.abs((x[0][1] - x[1][1]))
            x = xt
            y = yt
        else:
            logger.warning('x    should    be    in    the    form    [(x1,y1),(x2,y2)]')
            return None
    elif (isinstance(x, (tuple, list)) and isinstance(y, (tuple, list)) and (w == None) and (h == None)):
        if ((len(x) == 2) and (len(y) == 2)):
            xt = np.min([x[0], y[0]])
            yt = np.min([x[1], y[1]])
            w = np.abs((y[0] - x[0]))
            h = np.abs((y[1] - x[1]))
            x = xt
            y = yt
        else:
            logger.warning('if    x    and    y    are    tuple    it    should    be    in    the    form    (x1,y1)    and    (x2,y2)')
            return None
    if ((y == None) or (w == None) or (h == None)):
        print 'Please    provide    an    x,    y,    width,    height    to    function'
    if ((w <= 0) or (h <= 0)):
        logger.warning("Can't    do    a    negative    crop!")
        return None
    retVal = cv.CreateImage((int(w), int(h)), cv.IPL_DEPTH_8U, 3)
    if ((x < 0) or (y < 0)):
        logger.warning('Crop    will    try    to    help    you,    but    you    have    a    negative    crop    position,    your    width    and    height    may    not    be    what    you    want    them    to    be.')
    if centered:
        rectangle = (int((x - (w / 2))), int((y - (h / 2))), int(w), int(h))
    else:
        rectangle = (int(x), int(y), int(w), int(h))
    (topROI, bottomROI) = self._rectOverlapROIs((rectangle[2], rectangle[3]), (self.width, self.height), (rectangle[0], rectangle[1]))
    if (bottomROI is None):
        logger.warning("Hi,    your    crop    rectangle    doesn't    even    overlap    your    image.    I    have    no    choice    but    to    return    None.")
        return None
    retVal = np.zeros((bottomROI[3], bottomROI[2], 3), dtype='uint8')
    retVal = self.getNumpyCv2()[bottomROI[1]:(bottomROI[1] + bottomROI[3]), bottomROI[0]:(bottomROI[0] + bottomROI[2]), :]
    img = Image(retVal, colorSpace=self._colorSpace, cv2image=True)
    img._uncroppedX = (self._uncroppedX + int(x))
    img._uncroppedY = (self._uncroppedY + int(y))
    return img
