Add padding to images to get them into the same shape
The problem is here:
left= width_diff/2
right=width_diff/2
top=height_diff/2
bottom=height_diff/2
This will lead to different final width or height depending if the width_diff or height_diff is divisible by 2. You have a workaround implemented, but that will only work for Python 3 while you are apparently using Python 2.
You can fix this in this way:
left=width_diff/2
right=width_diff - left
top=height_diff/2
bottom=height_diff - top
In this way you will make sure that
- left + right = width_diff
- top + bottom = height_diff
Note that this in particular applicable to Python 2, you might be interested to read Python integer division yields float. My suggestion is to use floor division, so that your code is less vulnerable to the Python 2 and Python 3 differences.
left=width_diff//2
right=width_diff - left
top=height_diff//2
bottom=height_diff - top
Add padding to object in 4-channel image
The issue has been already addressed and solved here:
http://answers.opencv.org/question/90229/add-padding-to-object-in-4-channel-image/
python: Show numpy padded image by opencv
You can resolve the problem by reading with cv2.imread
and then convert to the gray-scale (black-and-white) image to the cv2.COLOR_BGR2GRAY
import cv2
import numpy as np
img = cv2.imread("input.jpg")
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
resized_digit = cv2.resize(gry, (18, 18))
padded_digit = np.pad(resized_digit, ((5, 5), (5, 5)), "constant", constant_values=0)
cv2.imshow("padded_digit", padded_digit)
cv2.waitKey(0)
imread
loads the image in BGR fashion, then you can convert it to the gray-scale using COLOR_BGR2GRAY
.
You can also use copyMakeBorder
(source) instead of np.pad
. Using np.pad
is not wrong, but opencv
is more suitable for image operations, since you are using opencv
functions like imshow
, waitKey
etc.
For instance:
import cv2
img = cv2.imread("input.jpg")
gry = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
resized_digit = cv2.resize(gry, (18, 18))
padded_digit = cv2.copyMakeBorder(resized_digit, 5, 5, 5, 5, cv2.BORDER_CONSTANT, value=0)
cv2.imshow("padded_digit", padded_digit)
cv2.waitKey(0)
You can check the two image equality by comparing their shapes. Both of them print(padded_digit.shape)
will be (28, 28)
Add transparent padding to image [closed]
This code works for me:
for imagePath in os.listdir(inPath):
# imagePath contains name of the image
inputPath = os.path.join(inPath, imagePath)
# inputPath contains the full directory name
img = Image.open(inputPath)
# fullOutPath contains the path of the output
fullOutPath = os.path.join(outPath, imagePath)
# add padding
img = ImageOps.expand(img, border=(10,10,10,10), fill=(0,0,0,0) )
# image that needs to be generated
img.save(fullOutPath)
print(fullOutPath)
how to pad images of different sizes and making them of same size by putting the original image in the middle in matlab?
You can use padarray to specify how many black pixels you want to add around the edge of the image.
Resizing and Padding Image with specific height and width in python OpenCV gives errors and inaccurate results
As I wrote in my comment above, the indentation is wrong: the for image in images
loop ends with the calculation of the ratio. Then you process just the last image in the images
list. Last has nothing to do with the file order in your folder, as walk
returns the files in arbitrary order.
Following is the code with correct indentation. It works perfectly:
import sys
import os
import numpy as np
from os import walk
import cv2
# width to resize
width = int(sys.argv[1])
# height to resize
height = int(sys.argv[2])
# location of the input dataset
input_dir = sys.argv[3]
# location of the output dataset
out_dir = sys.argv[4]
if len(sys.argv) != 5:
print("Please specify width, height, input directory and output directory.")
sys.exit(0)
print("Working...")
# get all the pictures in directory
images = []
ext = (".jpeg", ".jpg", ".png")
for (dirpath, dirnames, filenames) in walk(input_dir):
for filename in filenames:
if filename.endswith(ext):
images.append(os.path.join(dirpath, filename))
print(filename)
for image in images:
img = cv2.imread(image, cv2.IMREAD_UNCHANGED)
h, w = img.shape[:2]
pad_bottom, pad_right = 0, 0
ratio = w / h
if h > height or w > width:
# shrinking image algorithm
interp = cv2.INTER_AREA
else:
# stretching image algorithm
interp = cv2.INTER_CUBIC
w = width
h = round(w / ratio)
if h > height:
h = height
w = round(h * ratio)
pad_bottom = abs(height - h)
pad_right = abs(width - w)
scaled_img = cv2.resize(img, (w, h), interpolation=interp)
padded_img = cv2.copyMakeBorder(
scaled_img,0,pad_bottom,0,pad_right,borderType=cv2.BORDER_CONSTANT,value=[0,0,0])
cv2.imwrite(os.path.join(out_dir, os.path.basename(image)), padded_img)
print("Completed!")
How to automatically add zero padding in a image to expected shape?
For padding images to a target shape, you can use tf.image.resize_image_with_crop_or_pad(). This op crops the image if it is larger than target size, and pads (evenly on all sides) with zeros if it is smaller.
>>> a = tf.ones([3, 4, 3])
>>> tf.image.resize_image_with_crop_or_pad(a, 5, 5)
<tf.Tensor 'Squeeze:0' shape=(5, 5, 3) dtype=float32>
If you want to use padding, you can define a function to calculate padding amount using the difference between desired size and the shape of the tensor (tf.shape()) and pad the difference, check this answer for padding.
Create a padded image in python
From the plt.imshow
docs:
X : array-like or PIL image
The image data. Supported array shapes are:
- (M, N): an image with scalar data. The values are mapped to colors using normalization and a colormap. . . .
Normalization means that the colors are "spread out" so that the minimum is black and max is white. So those np.zeros
are making the minimum 0
(and the border black) and making everything else lighter to compensate. This should work to fix it (I think)
padded = np.pad(input,
pad_width = 1,
mode = 'minimum') # or mode = "maximum' for a white border
If you absolutely need a border of 0
, you can do:
padded = np.pad(input - input.min(),
pad_width = 1,
mode = 'constant')
That changes the range of your original picture to start a 0
, so the normalization should be the same.
Related Topics
How to Clear/Delete the Contents of a Tkinter Text Widget
How to Merge Columns from Multiple CSV Files Using Python
Pytest Cannot Import Module While Python Can
Keep Other Columns When Doing Groupby
Pyspark Add New Row to Dataframe
What Is the Simplest Way to Ssh Using Python
How to Get the Column Name in Pandas Based on Row Values
Python: Opencv - Selecting Region of an Image
Python: How to Find the First Day of Every Month Between Two Date Ranges
How to Extract Column Value Within Square Brackets in Pyspark
How to Get Slope from Timeseries Data in Pandas
Matplotlib: Drawing Lines Between Points Ignoring Missing Data
Regex to Find Words Between Two Tags
How to Remove Zeros After Decimal from String Remove All Zero After Dot
Python, Delete Json Element Having Specific Key from a Loop
How to Extract X,Y Coordinates from Opencv "Cv2.Keypoint" Object