I have two images and a mask. The first image (im1) is my source image, the second (im2) is the image whose region need to be inserted in im1 and the third image (mask) contains 1's in the region that needs to be pasted. All images have the same size (H*W*3). It should be noted that im1 is HDR( .exr format).
After reading via OpenCV
im1 = .imread(im1, cv2.IMREAD_ANYCOLOR | cv2.IMREAD_ANYDEPTH)[:,:,0:3]
im2 = ...
mask = ...
how can I transfer the masked region(contained in mask array) of image im2 without any loss of information (no change apart from masked region) in im1?
Normally you would use OpenCV's copyTo() method which will copy an image or masked image region from one Mat to another.
Unfortunately, this functionality is not available in the OpenCV Python bindings.
There is a Python workaround for this function from this answer though which you could use instead.
Related
I am trying to edit this image:
However, when I run
im = Image.open(filename)
im.show()
it outputs a completely plain white image of the same size. Why is Image.open() not working? How can I fix this? Is there another library I can use to get non-255 pixel values (the correct pixel array)?
Thanks,
Vinny
Image.open actually seems to work fine, as does getpixel, putpixel and save, so you can still load, edit and save the image.
The problem seems to be that the temp file the image is saved in for show is just plain white, so the image viewer shows just a white image. Your original image is 16 bit grayscale, but the temp image is saved as an 8 bit grayscale.
My current theory is that there might actually be a bug in show where a 16 bit grayscale image is just "converted" to 8 bit grayscale by capping all pixel values to 255, resulting in an all-white temp image since all the pixels values in the original are above 30,000.
If you set a pixel to a value below 255 before calling show, that pixel shows correctly. Thus, assuming you want to enhance the contrast in the picture, you can open the picture, map the values to a range from 0 to 255 (e.g. using numpy), and then use show.
from PIL import Image
import numpy as np
arr = np.array(Image.open("Rt5Ov.png"))
arr = (arr - arr.min()) * 255 // (arr.max() - arr.min())
img = Image.fromarray(arr.astype("uint8"))
img.show()
But as said before, since save seems to work as it should, you could also keep the 16 bit grayscale depth and just save the edited image instead of using show.
you can use openCV library for loading images.
import cv2
img = cv2.imread('image file')
plt.show(img)
I have an image that has one channel. I would like duplicate this one channel such that I can get a new image that has the same channel, just duplicated three times. Basically, making a quasi RBG image.
I see some info on how to do this with OpenCV, but not in PIL. It looks easy in Numpy, but again, PIL is different. I don't want to get into the habit of jumping from library to library all the time.
Here's one way without looking too hard at the docs..
fake image:
im = Image.new('P', (16,4), 127)
Get the (pixel) size of the single band image; create a new 3-band image of the same size; use zip to create pixel tuples from the original; put that into the new image..
w, h = im.size
ima = Image.new('RGB', (w,h))
data = zip(im.getdata(), im.getdata(), im.getdata())
ima.putdata(list(data))
Or even possibly
new = im.convert(mode='RGB')
just use:
image = Image.open(image_info.path).convert("RGB")
can convert both 1-channel and 4-channel to 3-channel
I'm trying to crop the image from the binary image which is already processed from the original, suppose I have the original image
and I got the binary image from the original
and I want to crop the image only the white area using blob analysis
How can I do that?
In c++ you can use,
cv::Mat output_Mat = cv::Mat::zeros(RGB_Mat.size(), RGB_Mat.type());
RGB_Mat.copyTo(output_Mat, Binary_Mat);
Hope you can find corresponding python methods.
points = cv2.findNonZero(binary_image);
min_rect = cv2.boundingRect(points);
I would like to create a panoramic image by combining 2 images in which the same feature, a plus sign.
I've used cv2.xfeatures2d.SIFT_create() to find keypoints in the image however it doesn't find the plus symbol very well. Is there some way I can improve this by making it search specifically for a plus-shaped feature?
import cv2
image1 = cv2.imread('example_image.png')
sift = cv2.xfeatures2d.SIFT_create()
kp = sift.detect(grey_image1, None)
kp_image = cv2.drawKeypoints(grey_image1, kp, None)
def showimage(image, name="No name given"):
cv2.imshow(name, image)
cv2.waitKey(0)
cv2.destroyAllWindows()
return
showimage(kp_image)
The source image is here, second image to align is here. Here is the resulting image from the code above. This is an example of the desired output made using GIMP and manually aligning the two images (the second image will need to transformed to fit properly).`
NB I'm open to using other approaches outside of OpenCV/Python to solve this problem.
Is there a function in PIL/Pillow that for a grayscale image, will separate the image into sub images containing the components that make up the original image? For example, a png grayscale image with a set of blocks in them. Here, the images types always have high contrast to the background.
I don't want to use openCV, I just need some general blob detection, and was hoping Pillow/PIL might have something that does that already.
Yes, it is possible. You can use edge detection algorithms in PIL.
Sample code:
from PIL import Image, ImageFilter
image = Image.open('/tmp/sample.png').convert('RGB')
image = image.filter(ImageFilter.FIND_EDGES)
image.save('/tmp/output.png')
sample.png :
output.png:
Not using PIL, but worth a look I think:
I start with a list of image files that I've imported as a list of numpy arrays, and I create a list of boolean versions where the threshold is > 0
from skimage.measure import label, regionprops
import numpy as np
bool_array_list= []
for image in image_files:
bool_array = np.copy(image)
bool_array[np.where(bool_array > 0)] = 1
bool_array_list.append(bool_array)
img_region_list = []
Then I use label to identify the different areas, using 8-directional connectivity, and regionprops gives me a bunch of metrics, such as size and location.
for item in bool_array_list:
tmp_region_list = regionprops(label(item,
connectivity=2
)
)
img_region_list.append(tmp_region_list)