Is there a way to save an adjusted image from a named Window in opencv in Python? - python-3.x

Just a general question - I made a contrast slider, so I could open images and adjust their brightness and/or contrast to what best fits my needs. However, how can I save those settings resp. overwrite the image with those settings once I close the window?

Unless I am misunderstanding your question, I think you just need to make sure you are saving the adjusted image to a different file path. The code below might help you. You can insert the datetime into the file name if you want a new image to be saved each time.
import cv2
from datetime import datetime
def some_adjustment(img):
"""
your adjustment
"""
return img
path = "img.jpg"
img = cv2.imread(path)
adjusted_img = some_adjustment(img)
cv2.imshow('adjusted_img', adjusted_img)
cv2.waitKey(0)
now = datetime.now()
dt_string = now.strftime("%m.%d.%Y.%H.%M.%S")
cv2.imwrite(f"adjusted_{dt_string}.png", adjusted_img)
cv2.destroyAllWindows()

Related

PIL Python3 - How can I open a GIF file using Pillow?

In my current condition, I can open an Image normally using a really short code like this
from PIL import Image
x = Image.open("Example.png")
x.show()
But I tried to use GIF format instead of png, It shows the file but it didn't load the frame of the GIF. Is there any possible way to make load it?
In My Current Code
from PIL import Image
a = Image.open("x.gif").convert("RGBA") # IF I don't convert it to RGBA, It will give me an error.
a.show()
Refer to Reading Sequences in the documentation:
from PIL import Image
with Image.open("animation.gif") as im:
im.seek(1) # skip to the second frame
try:
while 1:
im.seek(im.tell() + 1)
# do something to im
except EOFError:
pass # end of sequence

cv2.cvtColor(img,cv2.COLOR_BGR2RGB) not working

I am trying to create a screen recorder using mss and Opencv in python, the video I am capturing has a very different colours than original computer screen. I tried to find the solution online, Everyone saying it should be fixed using cvtColor() but I already have it in my code.
import cv2
from PIL import Image
import numpy as np
from mss import mss
import threading
from datetime import datetime
`
def thread_recording():
fourcc=cv2.VideoWriter_fourcc(*'mp4v')
#fourcc=cv2.VideoWriter_fourcc(*'XVID')
out=cv2.VideoWriter(vid_file,fourcc,50,(width,height))
mon = {"top": 0, "left": 0, "width":width, "height":height}
sct = mss()
thread1=threading.Thread(target=record,args=(mon,out,sct))
thread1.start()
def record(mon,out,sct):
global recording
recording=True
while recording:
frame= np.array(sct.grab(mon))
frame = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
out.write(frame)
out.release()
the vid_file variable contains a string of output file name with mp4 extension
Screenshot of my screen
Screenshot from recorded video
So, I looked around some more and found that apparently this is a bug in opencv for versions 3.x on wards.then I tried PIL for getting rgb image and removed cvtColor(),but it produced an empty video.I removed both cvtColor() as well as PIL Image as suggested by #ZdaR it again wrote empty video Hence I had to put it back and boom. even if cvtColor() seems like doing nothing, for some unknown reason it has to be there.when you use PIL Image along with cvtColor() it writes the video as expected
from PIL import Image
def record(mon,out,sct):
global recording
recording=True
while recording:
frame=sct.grab(mon)
frame = Image.frombytes('RGB', frame.size, frame.rgb)
frame = cv2.cvtColor(np.array(frame), cv2.COLOR_BGR2RGB)
out.write(np.array(frame))
out.release()
as I am very new to programming, I would really appreciate your help if I missed or overlooked something important
You can do
frameRGB = cv2.cvtColor(frame,cv2.COLOR_RGB2BGR)
Frame is in BGR, and it will work the same as you are only changing R with B where frameRGB is in RGB now. This command will transfer R to B and works to transfer frames from RGB and BGR as well as BGR to RGB. BGR2RGB might be a bug, I have it as well but the command I mentioned works perfectly. That's what I do.
MSS store raw BGRA pixels. Does it work if you change to:
# Grab it
img = np.array(sct.grab(mon))
# Convert from BGRA to RGB
frame = cv2.cvtColor(img, cv2.COLOR_BGRA2RGB)
you should run this command in cmd
pip install opencv-python

Both rasterio open and skimage.io.read return a NaN array for the TIFF I am trying to open

I'm trying to open a SAR image from sentinel-1. I can view the tiff file in QGIS, so I know the data is there, but when I go to open and view/show it in python, all of the modules I could use to open the data produce a NaN area, basically insinuating that there is no data in the image. Visualizing the image produces a completely black image, however the shape is correct.
Here is the code where I read in the image:
img = skimage.io.imread('NewData.tif', as_gray = True, plugin = 'tifffile')
with rio.open(r'NewData.tif') as src:
img2 = src.read()
imgMeta = src.profile
print(img)
skimage.io.imshow(img)
Any help would be appreciated.
thank you
The problem is not on the way rasterio or skimage is importing the image, but on the way it is displayed. I am assumign you are working with Calibrated SAR images that ARE NOT converted to the decibel dB scale. Here is the problem, the dynamic range of your data.
The issue here is that by default, the color ramp is not being strech according to the distribution of values in the raster histogram. In QGIS, SNAP or many other EO-related softwares, the color distribution matches the histogram to produce proper visualizations.
Solution: either you make that happen in your code or simply convert your backscatter values to decibel (which is a very common procedure when working with SAR data and produces an almost normal distrubution of the data). The conversion can be done in a EO software or more directly in your imported image with:
srcdB = 10*np.log10(src)
Once done, you can properly display your image:
import rasterio
from rasterio.plot import show
import numpy as np
with rio.open(r'/.../S1B_IW_GRDH_1SDV_20190319T161451_20190319T161520_015425_01CE3C_A401_Cal.tif') as src:
img2 = src.read()
imgMeta = src.profile
srcdB = 10*np.log10(src) # to decibel
show(srcdB, cmap='gray') # show using rasterio

Raw Images from rawpy darker than their thumbnails

I'm wanting to convert '.NEF' to '.png' using the rawpy, imageio and opencv libraries in Python. I've tried a variety of flags in rawpy to produce the same image that I see when I just open the NEF, but all of the images that output are extremely dark. What am I doing wrong?
My current version of the code is:
import rawpy
import imageio
from os.path import *
import os
import cv2
def nef2png(inputNEFPath):
parent, filename = split(inputNEFPath)
name, _ = splitext(filename)
pngName = str(name+'.png')
tempFileName = str('temp%s.tiff' % (name))
with rawpy.imread(inputNEFPath) as raw:
rgb = raw.postprocess(gamma=(2.222, 4.5),
no_auto_bright=True,
output_bps=16)
imageio.imsave(join(parent, tempFileName), rgb)
image = cv2.imread(join(parent, tempFileName), cv2.IMREAD_UNCHANGED)
cv2.imwrite(join(parent, pngName), image)
os.remove(join(parent, tempFileName))
I'm hoping to get to get this result:
https://imgur.com/Q8qWfwN
But I keep getting dark outputs like this:
https://imgur.com/0jIuqpQ
For the actual file NEF, I uploaded them to my google drive if you want to mess with it: https://drive.google.com/drive/folders/1DVSPXk2Mbj8jpAU2EeZfK8d2HZM9taiH?usp=sharing
You're not doing anything wrong, it's just that the thumbnail was generated by Nikon's proprietary in-camera image processing pipeline. It's going to be hard to get the exact same visual output from an open source tool with an entirely different set of algorithms.
You can make the image brighter by setting no_auto_bright=False. If you're not happy with the default brightening, you can play with the auto_bright_thr parameter (see documentation).

How to overlay images on each other in python and opencv?

I am trying to write images over each other. Ideally, what I want to do is to write every image in one folder over every image in another folder and output every unique image to another folder. So far, I am just working on having one image write over one image, but I can't seem to get that to work.
import numpy as np
import cv2
import matplotlib
def opencv_createsamples():
mask = ('resized_pos/2')
img = cv2.imread('neg/1')
new_img = img * (mask.astype(img.dtype))
cv2.imwrite('samp', new_img)
opencv_createsamples()
It would be helpful to have more information about your errors.
Something that stands out immediately is the lack of file type extensions. Your images are probably not being read correctly, to begin with. Also, image sizes would be a good thing to consider so you could resize as required.
If the goal is to blend images, considering the alpha channel is important. Here is a relevant question on StackOverflow:How to overlay images in python
Some other OpenCV docs that have helped me in the past: https://docs.opencv.org/trunk/d0/d86/tutorial_py_image_arithmetics.html
https://docs.opencv.org/3.1.0/d5/dc4/tutorial_adding_images.html
Hope this helps!

Resources