I have an Image showing below:
I need to crop the order using python coding. What I need is only the card. So I want to crop the border. How to do it??
This is the output I got using the code mentioned in the below comment.
I have an Image showing below:
I need to crop the order using python coding. What I need is only the card. So I want to crop the border. How to do it??
This is the output I got using the code mentioned in the below comment.
You could try using the Python Image Library PIL
from PIL import Image
img = Image.open("ImageName.jpg")
area_top = (125,70,444,253)
cropped_img_top = img.crop(area_top)
cropped_img_top.show()
img = Image.open("ImageName.jpg")
area_bottom = (125,306,444,490)
cropped_img_bottom = img.crop(area_bottom)
cropped_img_bottom.show()
if you want to edit multiple pictures automatically you could use following program which crops all .jpg files in the same folder as your python file:
import os
from PIL import Image
files = os.listdir()
for image_name in files:
if ".jpg" in image_name:
img = Image.open(image_name)
area_top = (125, 70, 444, 253)
cropped_img_top = img.crop(area_top)
cropped_img_top.save("cropped_top_"+image_name)
area_bottom = (125, 306, 444, 490)
cropped_img_bottom = img.crop(area_bottom)
cropped_img_bottom.save("cropped_bottom_"+image_name)
Edit: Ok, if you want it to find the corners itself you could try the following code. I just implemented a really basic corner finding algorithm which works fine on the image you provided, but I don't know how your other images look like so there might be problems there. It also took me a long time to code, so please use with appreciation ;)
Here is the code:
import os
from PIL import Image
import numpy as np
def convolution2d(matrix, kernel):
m, n = kernel.shape
y, x = matrix.shape
y = y - m + 1
x = x - m + 1
new_matrix = np.zeros((y, x))
for i in range(y):
for j in range(x):
new_matrix[i][j] = np.sum(matrix[i:i + m, j:j + m] * kernel)
return new_matrix
def widen(mask, amount):
return np.array([[mask[0][0]] * amount + [mask[0][1]] * amount] * amount +
[[mask[1][0]] * amount + [mask[1][1]] * amount] * amount)
def too_close(existing, new, max_dist):
for c in existing:
if (c[0] - new[0]) ** 2 + (c[1] - new[1]) ** 2 < max_dist ** 2:
return True
return False
def corner(bw, mask, corner_threshold, offset):
corner_hotmap = convolution2d(bw, mask)
corner_threshold = np.max(corner_hotmap) * corner_threshold
width = len(corner_hotmap)
height = len(corner_hotmap[0])
corners = []
for x in range(width):
for y in range(height):
if corner_hotmap[x][y] > corner_threshold:
if not too_close(corners, [x, y], 10):
corners.append([x + offset, y + offset])
return corners
def get_areas(image, brightness_threshold=100, corner_threshold=0.9, n_pix=4):
width = len(image)
height = len(image[0])
greyscale = np.zeros(shape=(width, height))
for x in range(width):
for y in range(height):
s = sum(image[x][y]) / 3
if s > brightness_threshold:
greyscale[x][y] = 1
else:
greyscale[x][y] = -1
top_left = widen([[-1, -1, ], [-1, 1, ]], n_pix)
bottom_right = widen([[1, -1, ], [-1, -1, ]], n_pix)
corners_topleft = corner(greyscale, top_left, corner_threshold, n_pix)
corners_bottomright = corner(greyscale, bottom_right, corner_threshold, n_pix)
if len(corners_topleft) != len(corners_bottomright):
return []
else:
out = []
for i in range(len(corners_topleft)):
out.append((corners_topleft[i][1], corners_topleft[i][0], corners_bottomright[i][1],
corners_bottomright[i][0]))
return out
files = os.listdir()
for image_name in files:
if ".jpg" in image_name:
img = Image.open(image_name)
width = img.size[0]
height = img.size[1]
image = np.array(Image.open(image_name).getdata()).reshape(height, width, 3)
print("Getting Areas for file {}.".format(image_name))
areas = get_areas(image)
if len(areas)==0:
print("Could not find corners for file {}.".format(image_name))
else:
print("Found {} cards".format(len(areas)))
for i in range(len(areas)):
cropped_img = img.crop(areas[i])
cropped_img.save("cropped_{}_{}".format(i, image_name))
Finding corners is not easy. This algorithm works well on the Image you provided, however I do not know how the other images look like and if this will work on those as well. Good luck with cropping your Images ^^
All you need to do is slicing arrays. First supply the startY and endY coordinates, followed by the startX and endX coordinates to the slice. That’s it. Your image will be cropped!
Steps using Python and OpenCV:
1) load the image and display it on screen
# import the necessary packages
import cv2
# load the image and show it
image = cv2.imread("cardWithBorder.jpg")
cv2.imshow("original", image)
cv2.waitKey(0)
2) Get the dimensions of the image
print image.shape
3) Cropping the image
# crop the image using array slices -- it's a NumPy array
# after all!
cropped = image[70:170, 440:540]
cv2.imshow("cropped", cropped)
cv2.waitKey(0)
4) Save the cropped image to disk, only in PNG format (the original was a JPG):
cv2.imwrite("thumbnail.png", cropped)
Maybe you can use a different approach using opencv
, where you create a gray mask to get only the interesting areas of the image. You can do that like this:
#import the necessary packages
import numpy as np
import cv2
#read the image
image = cv2.imread('image.jpg')
#rgb values for grey color in pixels
lower = np.array([80,70,70],dtype='uint8')
upper = np.array([95,85,85],dtype='uint8')
#create a grey mask and then the inverse of that mask
mask = cv2.inRange(image,lower,upper)
mask_inv = cv2.bitwise_not(mask)
output = cv2.bitwise_and(image,image,mask=mask_inv)
# display the result
cv2.imshow('images',np.hstack([output]))
cv2.waitKey(0)
Assuming you want to extract cards that don't have the same shape/positioning every time, that technique might come in handy.