I have been working on the background removal project, for that to segment the image I used u2net model. after that I used Image.BILINEAR to remove resample the image, then I convert into RGBA and deployed it in to aws .
After converting that I have a little bit of shadow is remaining in the image edges, is there any way to remove the image edges shadow.
This my original image:
This is my background removal image:
Here my code:
output = predict(model, np.array(image))
output = output.resize((image.size), resample=Image.BILINEAR) # remove resample
empty_img = Image.new("RGBA", (image.size), 0)
new_img = Image.composite(image, empty_img, output.convert("L"))
Related
I've got the following image:
And I'm doing the following
First I read an image img = skimage.io.imread('original.jpg') that has the following histogram:
Then, after applying he_img = skimage.exposure.equalize_hist(a), I get the following histogram:
but when I save, then load and see the histogram of that image I get the following:
skimage.io.imsave(fname = 'he.jpg', arr= he_img)
saved = skimage.io.imread('he.jpg')
What else do I need to add to my process in order to being able to save the equalized image?
The problem with this was that I was using JPG. JPG uses lossy compression to save images, adding noise to the image affecting to the equalization and increassing the images entropy.
To solve this I tried PNG that is a lossless compression format for storing images. The code for this is:
img = skimage.io.imread('original.jpg')
hist_equalized_img = skimage.exposure.equalize_hist(img)
skimage.io.imsave(fname = 'he.png', arr= hist_equalized_img)
I am trying to do a pyramid of tiles with a non-square image (width: 32768px and height: 18433px)
I am using libvips as follows:
vips dzsave my_image.tif out_folder --layout google --suffix .png
For the same purpose I have also used gdal2tiles:
python gdal2tiles.py -p raster -z 0-7 -w none my_image.tif
Because my image is not square, some padding is necessary when the 256x256 tiles are created. Padding however is different between vips and gdal2tiles. The former adds padding at the bottom of the tile where as the latter at the top (and is trasparent). See image below. What is shown in the the 256x256 tile at the root of the pyramid (ie zoom level=0). I have manually added the yellow background and the black outline.
With vips, is it possible to have similar padding to gdal2tiles so that the bottom-left corner of the tile coincide with that from the image? I am plotting points on my image, hence it helps to have the origin at the bottom-left.
How can I also have transparent background with vips? (that might better be in a separate post though...)
You can run dzsave as the output of any vips operation by using .dz as the file extension and putting the arguments in square brackets after the filename. For example, this command:
vips dzsave my_image.tif out_folder --layout google --suffix .png
Can also be written as:
vips copy my_image.tif out_folder.dz[layout=google,suffix=.png]
So you can solve your problem by expanding your input image to a square before running dzsave.
For example:
$ vips gravity Chicago.jpg dir.dz[layout=google,suffix=.png,skip_blanks=0] south-west 32768 32768 --extend white
32768 is the nearest power of two above that image width. The skip_blanks option makes dzsave not output tiles equal to the blank background tile.
That command makes this dir/0/0/0.png:
(I added the black lines to show the edges)
To get a transparent background, you need to add an alpha. This would require another command, and is beyond what the vips CLI is really designed for.
I would switch to something like Python. With pyvips, for example, you can write:
import sys
import pyvips
im = pyvips.Image.new_from_file(sys.argv[1], access='sequential')
im = im.addalpha()
# expand to the nearest power of two larger square ... by default, gravity will
# extend with 0 (transparent) pixels
size = 1 << int.bit_length(max(im.width, im.height))
im = im.gravity('south-west', size, size)
im.dzsave(sys.argv[2],
layout='google', suffix='.png', background=0, skip_blanks=0)
Run like this:
$ ./mkpyr.py ~/pics/Chicago.jpg x
To make this x/0/0/0.png:
(added the green background to show the transparency)
I am using opencv in python to rotate an image and the original and the resulted images are differrent is somethings, I am doing my transformation through this part of code:
img = cv2.imread("image.tif")
new_image = cv2.getRotationMatrix2D((cols / 2, rows / 2), correction_angle, 1)
dst = cv2.warpAffine(img, new_image , (cols, rows))
cv2.imwrite("Rotated_image.tif", dst)
The original image's size is 1.7 Mb, The image's resolution is 300
dpi, and the color space is YCbCr.
The issue is that the resulting image with 12.5 Mb size, 96 dpi, the color space is RGB, and with compression "LZW"!
My question is that: Can I keep the main properties of the original image? and why rotating an image changes the size this way?
Note: The bit depth is 24 in both images.
Calling cv2.imread with only the name of the file uses the default value cv.IMREAD_COLOR for the second parameter, about which the documentation says:
If set, always convert image to the 3 channel BGR color image.
So, your image is always converted to RGB. You can try using cv.IMREAD_ANYCOLOR for the second parameter of imread, but I don't think you can use cv2.warpAffine on it trivially then.
The difference in the stored DPI information stems from the fact that you write the new image without any meta data. imwrite allows you to specify parameters (see here), but, unfortunately, they are not very well documented. I am not sure if this kind of data can be written out of the box with OpenCV.
I am doing a comparison with imagemagick on a project. I have a reference image and test image. I deleted few lines to make changes in test image. This reduced the size of test image. Is there any way that if I could add some white padding at bottom to test image so that while comparing reference image and test image the size of two images remains same.
Please help!
convert -border 5x5 inputimage.png outputimage.png
This command will draw a 5x5 pixel border around your image. Further, you can selectively control at the edges, color and size of the borders drawn on an image. This link will show how to do that.
I would like to add a smaller image on top of a larger image (eventually for PiP on a video feed). I can do it by iterating through the relevant data property in the large image and add the pixels from the small image. But is there a simpler and neater way? I'm using EMGU.
My idea was to define an ROI in the large image of the same size as the small image. Set the Large image equal to the small image and then simply remove the ROI. Ie in pseudo code:
Large.ROI = rectangle defined by small image;
Large = Small;
Large.ROI = Rectangle.Empty;
However this doesn't work and the large image doesn't change. Any suggestions would be much appreciated.
Large image:
Small image:
Desired result:
If you using C++ API then the following code snippet should work:
cv::Mat big;
cv::Mat small;
// Define roi area (it has small image dimensions).
cv::Rect roi = cv::Rect(50,50, small.cols, small.rows);
// Take a sub-view of the large image
cv::Mat subView = big(roi);
// Copy contents of the small image to large
small.copyTo(subView);
Take care to not go out of dimensions of big image.
I don't know if this will help, i haven't used emgu. However this was how i was able to do image in image with opencv.
drawIntoArea(Mat &src, Mat &dst, int x, int y, int width, int height)
{
Mat scaledSrc;
// Destination image for the converted src image.
Mat convertedSrc(src.rows,src.cols,CV_8UC3, Scalar(0,0,255));
// Convert the src image into the correct destination image type
// Could also use MixChannels here.
// Expand to support range of image source types.
if (src.type() != dst.type())
{
cvtColor(src, convertedSrc, CV_GRAY2RGB);
}else{
src.copyTo(convertedSrc);
}
// Resize the converted source image to the desired target width.
resize(convertedSrc, scaledSrc,Size(width,height),1,1,INTER_AREA);
// create a region of interest in the destination image to copy the newly sized and converted source image into.
Mat ROI = dst(Rect(x, y, scaledSrc.cols, scaledSrc.rows));
scaledSrc.copyTo(ROI);
}
I have a lot of experience with EMGU. As far as I am aware the method your employing is the only direct way of display the sub-image data within your large image. You would likely have to refresh your larger image which would have the inherent effect of wiping your transferred data and copy the smaller image back over.
While a solution is possible I think the method is flawed. The required processing time will effect the display rate of any image in the larger viewing frame.
An improved method would be to add another control. Effectively you have your video feed window showing your larger image in the background and a smaller control on-top of this displaying your smaller image. Effectively you could have as many of these smaller controls as you like. You will in effect be displaying two images or video feeds in two different controls (e.g. image boxes). As you have the code to do so all you will have to do is ensure the order of which your controls are displayed.
I have assumed you are not programming the output to a Console Window. If you need any more help please feel free to ask.
As for the comments EMGU is written in C# and while appreciate your view on not calling EMGU OpenCV why should it not be tagged as an OpenCV orientated question. After all EMGU is simply OpenCV library with a c# wrapper. I have found many resources on OpenCV useful for EMGU and vice versa.
Cheers
Chris
Based on #BloodAxe's answer, using EMGU 3.4 the following works:
// Define roi area (it has small image dimensions).
var ROI = new System.Drawing.Rectangle(100, 500, 200, 200)
// Take a sub-view of the large image
Mat subView = new Mat(bigImage, ROI);
// Copy contents of the small image to large
small.CopyTo(subView);