Issue
I drew a straight line by changing the color of 50 pixels in the image below. The line is the diagonal line shown on the image
Here is how I did it.
zeros = torch.zeros_like(img) #img is b,c,h,w
x1, y1, x2, y2, r, g, b = 16, 50, 100, 100, 6, 2, 4
rgb = torch.tensor([r, g, b])
cx, cy = x2 - x1, y2 - y1
for t in np.linspace(0, 1, 50):
px, py = x1 + t * cx, y1 + t * cy
zeros[0, :, int(py), int(px)] = rgb
mask = (zeros == 0).float()
im = mask * img + (1 - mask) *zeros
It is obvious in np.linspace(0, 1, 50)
that I am changing 50 pixels. I want to use the same method to change a specific portion of the image, like a 14 x 14
patch of my image if the image size is 224 x 224
or even more. The range of pixels to cover now will be 196 -> (since there are 196 pixels in a 14 x 14
patch) instead of 50. How do I go about it, please?
Solution
I assume that img
dimensions are BCHW based on the comment in the first line.
You can change values pixel by pixel in a for loop (which is quite inefficient):
img[0, :, y, x] = rgb
Or you can change the whole patch. Assuming img
is Numpy ndarray
and you want to reduce intensity:
img[0, :, 100:200, 100:200] = (img[0, :, 100:200, 100:200] / 1.3).astype(np.uint8)
Just put attention to dimensions and data types. You have to convert the result to uint8
, same as original image.
To set some intensity gradient on the patch:
gradient = np.tile(np.linspace(0.2, 0.9, 100), (3, 100, 1))
img[0, :, 100:200, 100:200] = (img[0, :, 100:200, 100:200] * gradient).astype(np.uint8)
Here 0.2-0.9
is intensity and 100
is the patch size. So gradient
is 3x100x100 tensor. I create it by taking a vector of intensities of shape (100,) and tiling it so it becomes a 3x100x100 tensor. The last line is a multiplication of each value in img
by corresponding value in gradient
.
When working with images it is much more convenient to represent them in HWC format. You can easily achieve that by writing
img = img[0].transpose(1,2,0)
This will swap dimensions CHW->HWC (as Batch is removed by indexing [0] ). Then you can easily write:
img[y:y+patch_h, x:x+patch_w] = rgb
and Python will automatically will try to fit missing dimension. In this case a 3-d vector rgb
will be broadcasted to patch_h
xpatch_w
x3
tensor. Same logic works for Python native arrays
, NumPy ndarray
, Pytorch and TF tensors. Then you can (for example) flip a patch by
img[y:y+patch_h, x:x+patch_w] = np.fliplr(img[y:y+patch_h, x:x+patch_w])
Answered By - igrinis
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.