How to draw a picture by OpenCV within Gtk in Python - python-3.x

I am struggling with the integration of OpenCV with in my Python Gtk application. What I am trying to do, is to load a picture like this:
pic = cv2.imread("image.jpg") #pic is a numpy.ndarray
Afterwards, I would like to display this image using a GtkWidget. But actually I have no idea how. My first idea was to use something like GtkImage, but GtkImage can only work directly with an image file. Since my plan is to manipulate a video-stream this is not practicable.
Maybe one of you has an idea how to proceed. Thank you very much.

I found a solution. So for anyone how is interested I did it like this:
self.frame = Gtk.Frame()
pic = cv2.imread("image.jpg")
pic = cv2.resize(pic, (400,600))
pic = np.array(pic).ravel()
print(pic.size)
pixbuf = GdkPixbuf.Pixbuf.new_from_data(pic,GdkPixbuf.Colorspace.RGB, False, 8, 600, 400, 3*600)
Image = Gtk.Image.new_from_pixbuf(pixbuf)
self.frame.add(Image)

Related

Python and Kivy: How to update Image from memory?

I'm currently trying to display an image with kivy on a Raspbery Pi 4. The problem is that no image is shown on the Image widget. Also no Error or something else is given out to the terminal.
This is what I came up with in show_picture() in .py file:
image = camera.takePicture()
encode_param = [int(cv.IMWRITE_JPEG_QUALITY), 95]
result, enc_img = cv.imencode('.jpg', image, encode_param)
data = io.BytesIO(enc_img)
texture_ = CoreImage(data, ext="jpg").texture
The texture_ object was declared and initialized at class level with:
texture_ = StringProperty(None)
And in the .kv file I have following for the Image widget:
Image:
id: imageView
source: app.texture_
allow_stretch: True
I want the image to be updated via this method so that the gui shows the latest taken image. If someone has a different approach I'm also happy with it.
Thanks in advance.
Edit: messed something up when copying code

Tkinter and some kind of issue when trying to display images

First off, I'm very new to Python and coding in general. I'm using Python, Tkinter, and Idle version 3.7.3. I'm using an HP Chromebook, with Chrome OS Version 81.0.4044.141.
from tkinter import *
window = Tk()
window.title('Image Example')
img = PhotoImage(file = 'python.gif')
label = Label(window, image = img)
label.pack()
window.mainloop()
As you can see above, this is the small snippet of code that I'm having issues with. As far as I understand, everything is written correctly and the file "python.gif" is in the correct directory. For reference this is what the image should look like:
python.gif (normal)
But when I run the program, this is what I get:
python.gif (screenshot of running program)
That's the result 99% of the time, but I should mention that there have been a RARE number of occasions where the image displayed correctly upon program execution. However, I do not know how to replicate that. Also for more context, I've tried other images to see what happened. I found a free .pgm image to try as an example, and upon execution either I got the same result, or half of the image would appear correctly while the bottom half (also sometimes this would be reversed and the top half would be affected) would be "blacked out".
In conclusion, I wanted to ask if anybody has an idea of what's going on. I'm not sure if this is a hardware issue (because I can view all mentioned images in a normal image viewing app with no problems), or if this has something to do with Python/Tkinter.
Any assistance is very appreciated! Please and Thank You!

Problems Converting Numpy/OpenCV Array Image into a Wand Image

I'm currently trying to perform a Polar to Cartesian Coordinate Image transformation, to display a raw sonar image into a 'fan-display'.
Initially I have a Numpy Array image of type np.float64, that can be seen below:
After doing some searching, I came across this StackOverflow post Inverse transform an image from Polar to Cartesian in OpenCV with a very similar problem, in which the poster seemed to have solved his/her issue by using the Python Wand library (http://docs.wand-py.org/en/0.5.9/index.html), specifically using their set of Distortion functions.
However, when I tried to use Wand and read the image in, I instead ended up with Wand getting the image below, which seems to be smaller than the original one. However, the weird thing is that img.size still gives the same size number as the original image's shape.
The code for this transformation can be seen below:
print(raw_img.shape)
wand_img = Image.from_array(raw_img.astype(np.uint8), channel_map="I") #=> (369, 256)
display(wand_img)
print("Current image size", wand_img.size) #=> "Current image size (369, 256)"
This is definitely quite problematic as Wand will automatically give the wrong 'fan image'. Is anybody familiar with this kind of problem with the Wand library previously, and if yes, may I ask what is the recommended solution to fix this issue?
If this issue isn't resolved soon I have an alternative backup of using OpenCV's cv::remap function (https://docs.opencv.org/4.1.2/da/d54/group__imgproc__transform.html#ga5bb5a1fea74ea38e1a5445ca803ff121). However the problem with this is that I'm not sure what mapping arrays (i.e. map_x and map_y) to use to perform the Polar->Cartesian transformation, as using a mapping matrix that implements the transformation equations below:
r = polar_distances(raw_img)
x = r * cos(theta)
y = r * sin(theta)
didn't seem to work and instead threw out errors from OpenCV as well.
Any kind of help and insight into this issue is greatly appreciated. Thank you!
- NickS
EDIT I've tried on another image example as well, and it still shows a similar problem. So first, I imported the image into Python using OpenCV, using these lines of code:
import matplotlib.pyplot as plt
from wand.image import Image
from wand.display import display
import cv2
img = cv2.imread("Test_Img.jpg")
img_rgb = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.figure()
plt.imshow(img_rgb)
plt.show()
which showed the following display as a result:
However, as I continued and tried to open the img_rgb object with Wand, using the code below:
wand_img = Image.from_array(img_rgb)
display(img_rgb)
I'm getting the following result instead.
I tried to open the image using wand.image.Image() on the file directly, which is able to display the image correctly when using display() function, so I believe that there isn't anything wrong with the wand library installation on the system.
Is there a missing step that I required to convert the numpy into Wand Image that I'm missing? If so, what would it be and what is the suggested method to do so?
Please do keep in mind that I'm stressing the conversion of Numpy to Wand Image quite crucial, the raw sonar images are stored as binary data, thus the required use of Numpy to convert them to proper images.
Is there a missing step that I required to convert the numpy into Wand Image that I'm missing?
No, but there is a bug in Wand's Numpy implementation in Wand 0.5.x. The shape of OpenCV's ndarray is (ROWS, COLUMNS, CHANNELS), but Wand's ndarray is (WIDTH, HEIGHT, CHANNELS). I believe this has been fixed for the future 0.6.x releases.
If so, what would it be and what is the suggested method to do so?
Swap the values in img_rgb.shape before passing to Wand.
img_rgb.shape = (img_rgb.shape[1], img_rgb.shape[0], img_rgb.shape[2],)
with Image.from_array(img_rgb) as img:
display(img)

Photutils DAOPhot Not Fitting stars well?

I recently ran across the PhotUtils package and am trying to use it to perform PSF Photometry on some images I have. However, when I try to run the code, I get very strange results. When I plot the image generated by get_residual_image(), the stars are not removed well. Some sample images are shown below.
The first image has sigma set to 2.05, as it is in one of the sample programs in the PhotUtils documentation:
However, the stars only appear to be removed in their center.
The second image has sigma set to 5.0. This one is especially strange. Some stars are way over-removed, some are under removed, some black squares are added to the image, etc.
Here is my code:
import photutils
from photutils.psf import DAOPhotPSFPhotometry as DAOP
from photutils.psf import IntegratedGaussianPRF as PRF
from photutils.background import MMMBackground
bkg = MMMBackground()
background = 2.5*bkg(img)
gaussian_prf = PRF(sigma=5.0)
gaussian_prf.sigma.fixed = False
photTester = DAOP(8,background,5,gaussian_prf,31)
photResults = photTester(imgStars)
finalImg = photTester.get_residual_image()
After this, I simply plot the original and final image in MatPlotLib. I use a greyscale colormap. The reason that the left images appear slightly darker is that they use a different color scaling.
Perhaps I have set one of the parameters incorrectly?
Could someone help me out with this? Thank you!
Looking at the residual image instantly told me that the background subtraction might be wrong. I could reproduce the result and wondered, if MMMBackground did not do the job correctly.
After taking a closer look at the documentation, Getting startet with Photutils finally gave the essential hint:
image -= np.median(image)

how to correct the orientation of the image with ITK-VTK

I am a beginner in VTK ITK, I am trying to read a DICOM series with ITK and display with VTK but I had pictures upside down, I tried to read a single image (JPG) with ITK and visualuser with VTK it is the same problem, so I had the idea of ​​treating the image on photoshop ie I applied to the original image rotation (vertical symmetry of the work area) and I did the reading with ITK and display with VTK, the image is displayed in the correct orientation, infact ITK keeps the orientation of the image, but the problem is at VTK, it is which displays the image upside down, I searched all over the internet I have not found a solution or a method or not even an idea, I encountered the same problem in many forums but there is no response, I count on your help, I can not apply any image processing to find a solution to this problem.
Please Help! thank you in advance
Ideally you should re-orient your camera in VTK so that it is suited for medical image visualization. (The default camera in VTK uses the computer graphics conventions).
If you want a quick hack, you can copy-paste the following code in ITK:
FlipFilterType::Pointer flipperImage = FlipFilterType::New();
bool flipAxes[3] = { false, true, false };
flipperImage = FlipFilterType::New();
flipperImage->SetFlipAxes(flipAxes);
flipperImage->SetInput( image );
flipperImage->Update();
I use a rapid way to set the orientation:
imageActor->SetOrientation(180,0,0);
No need to add filter.
Here's an example of how I would do it. I'm not sure what classes you are using, so I cannot be specific.
vtkSmartPointer<vtkImageData> result = vtkSmartPointer<vtkIMageData>::New();
result->DeepCopy(YourImage); //DeepCopy your image to result
rImage->Update();
double val;
int i = 0;
for(vtkIdType f = result->GetNumberOfPoints()-1; f > -1; f--)
{
val = YourImage->GetPointData()->GetScalars()->GetTuple1(f);
result->GetPointData()->GetScalars->SetTuple1(i,val);
i++;
}
result->Update();
//Now Visualize your image

Resources