根据所选择的坐标裁剪图像

时间:2016-09-14 14:35:57

标签: opencv image-processing

我有这样的输入图像

enter image description here

由于它是一个矩形,因此很容易裁剪红点。如果2,3,6和7上的红点动态移动到绿点,我该如何裁剪。这些点可能会改变我在程序中动态裁剪的方式。

结果可能如下所示

enter image description here

我尝试过Warppperspective,但我无法得到预期的结果。 该计划就像这样

import matplotlib.pyplot as plt
import numpy as np
import cv2

img = cv2.imread('sudoku_result.png')

pts1 = np.float32([[100,60],[260,60],[100,180],[260,180],[100,300],[260,300]])
pts2 = np.float32([[20,60],[340,60],[60,180],[300,180][100,300],[260,300]])

M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(360,360))


plt.subplot(121),plt.imshow(img),plt.title('Input')
plt.subplot(122),plt.imshow(dst),plt.title('Output')
plt.show()

我是图像处理的新手,想知道哪种方法最好。

2 个答案:

答案 0 :(得分:3)

裁剪由(minX,minY,maxX,maxY)创建的矩形的封闭矩形,然后对于裁剪图像中的每个像素,您可以检查由原始点创建的多边形内部的点以及外部点你把零的原始形状。

代码:

import cv2
import numpy as np

# Read a image
I = cv2.imread('i.png')

# Define the polygon coordinates to use or the crop
polygon = [[[20,110],[450,108],[340,420],[125,420]]]

# First find the minX minY maxX and maxY of the polygon
minX = I.shape[1]
maxX = -1
minY = I.shape[0]
maxY = -1
for point in polygon[0]:

    x = point[0]
    y = point[1]

    if x < minX:
        minX = x
    if x > maxX:
        maxX = x
    if y < minY:
        minY = y
    if y > maxY:
        maxY = y

# Go over the points in the image if thay are out side of the emclosing rectangle put zero
# if not check if thay are inside the polygon or not
cropedImage = np.zeros_like(I)
for y in range(0,I.shape[0]):
    for x in range(0, I.shape[1]):

        if x < minX or x > maxX or y < minY or y > maxY:
            continue

        if cv2.pointPolygonTest(np.asarray(polygon),(x,y),False) >= 0:
            cropedImage[y, x, 0] = I[y, x, 0]
            cropedImage[y, x, 1] = I[y, x, 1]
            cropedImage[y, x, 2] = I[y, x, 2]

# Now we can crop again just the envloping rectangle
finalImage = cropedImage[minY:maxY,minX:maxX]

cv2.imwrite('finalImage.png',finalImage)

最终图片:

enter image description here

如果你想拉伸歪曲的图像

# Now strectch the polygon to a rectangle. We take the points that
polygonStrecth = np.float32([[0,0],[finalImage.shape[1],0],[finalImage.shape[1],finalImage.shape[0]],[0,finalImage.shape[0]]])

# Convert the polygon corrdanite to the new rectnagle
polygonForTransform = np.zeros_like(polygonStrecth)
i = 0
for point in polygon[0]:

    x = point[0]
    y = point[1]

    newX = x - minX
    newY = y - minY

    polygonForTransform[i] = [newX,newY]
    i += 1


# Find affine transform
M = cv2.getPerspectiveTransform(np.asarray(polygonForTransform).astype(np.float32), np.asarray(polygonStrecth).astype(np.float32))

# Warp one image to the other
warpedImage = cv2.warpPerspective(finalImage, M, (finalImage.shape[1], finalImage.shape[0]))
cv2.imshow('a',warpedImage)

enter image description here

答案 1 :(得分:1)

看起来你提到的坐标不准确。所以调整坐标以匹配形状并使用Cloudinary扭曲功能补充自定义形状裁剪,结果如下:

http://res.cloudinary.com/demo/image/fetch/e_distort:20:60:450:60:340:410:140:410,l_sample,fl_cutter,g_north_west/e_trim/http://i.stack.imgur.com/oGSKW.png

如果您喜欢使用这些Cloudinary函数,请参阅以下示例: http://cloudinary.com/blog/how_to_dynamically_distort_images_to_fit_your_graphic_design http://cloudinary.com/cookbook/custom_shapes_cropping