cv2.imwrite not giving image output - python-3.x

I'm currently doing an internship remotely and I got to code a Visualization Tool with D3.JS but here is not the part where I got a problem.
To fix the subject I got some file called episodes, which contain data about the path of a robot, if he succeeds or failed and the different point in cartesian coordinate.
(BTW I'm French I apologize in advance if there is some grammar issues)
So I got a small Python program that interpret these data contained in these .p files here's the code :
import pickle
import matplotlib.pyplot as plt #PyQT is require or tkinter
import numpy as np
import cv2
#This script aligns the true position to position given by orbslam.
#Load episode with id. #This loads the dictionary containing all information about an episode.
trajectory_dir = "ORBSlam/"
episode_id = 0
episode = pickle.load(open( trajectory_dir+"episodeStats"+str(episode_id)+".p", "rb" ))
#Extract useful data from the dictionary
pose_env = episode["pose_env"]
images_RGB = episode["rgb"]
images_depth = episode["depth"]
actions_orb = episode["orb_action"]
actions_best = episode["best_action"]
goal_distances = episode["goal_distance"]
success = episode["success"]
#Save observations into images.
for i in range(len(images_RGB)):
cv2.imwrite( trajectory_dir+"RGBs"+str(episode_id)+"/"+str(i)+".png", images_RGB[i] )
cv2.imwrite( trajectory_dir+"Depths"+str(episode_id)+"/"+str(i)+".png", images_depth[i]*255 )
#Display 2D trajectories.
x_env = []
y_env = []
for i in range(len(pose_env)):
#add x,y coordinates of the translation
x_env.append(pose_env[i][0,3])
y_env.append(pose_env[i][2,3])
plt.plot(x_env,y_env)
plt.axis('equal')
plt.show()
The problem here is that during the loop where it's supposed to output png image, in fact there is no output in the folder and since it's a silent function I don't know what the error is, I created both folder in ORBSlam folder (RGBs and Depths), so do you think it's something about permissions of writing or something like that ? (I'm working on macOS)
Thanks in advance for all the responses.
EDIT : I find why I've got no output images, I simply forgot to create a folder with the name of episode_id (Basically 0,1,2,...) in Depths and RGBs folder, my bad it was a dumb mistake

Solved : a folder inside where missing to get the output

Related

Removing Gridlines from Scanned Graph Paper Documents

I would like to remove gridlines from a scanned document using Python to make them easier to read.
Here is a snippet of what we're working with:
As you can see, there are inconsistencies in the grid, and to make matters worse the scanning isn't always square. Five example documents can be found here.
I am open to whatever methods you may suggest for this, but using openCV and pypdf might be a good place to start before any more involved breaking out the machine learning techniques.
This post addresses a similar question, but does not have a solution. The user posted the following code snippet which may be of interest (to be honest I have not tested it, I am just putting it here for your convivence).
import cv2
import numpy as np
def rmv_lines(Image_Path):
img = cv2.imread(Image_Path)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
edges = cv2.Canny(gray,50,150,apertureSize = 3)
minLineLength, maxLineGap = 100, 15
lines = cv2.HoughLinesP(edges,1,np.pi/180,100,minLineLength,maxLineGap)
for x in range(0, len(lines)):
for x1,y1,x2,y2 in lines[x]:
#if x1 != x2 and y1 != y2:
cv2.line(img,(x1,y1),(x2,y2),(255,255,255),4)
return cv2.imwrite('removed.jpg',img)
I would prefer the final documents be in pdf format if possible.
(disclaimer: I am the author of pText, the library being used in this answer)
I can help you part of the way (extracting the images from the PDF).
Start by loading the Document.
You'll see that I'm passing an extra parameter in the PDF.loads method.
SimpleImageExtraction acts like an EventListener for PDF instructions. Whenever it encounters an instruction that would render an image, it intercepts the instruction and stores the image.
with open(file, "rb") as pdf_file_handle:
l = SimpleImageExtraction()
doc = PDF.loads(pdf_file_handle, [l])
Now that we have loaded the Document, and SimpleImageExtraction should have had a chance to work its magic, we can output the images. In this example I'm just going to store them.
for i, img in enumerate(l.get_images_per_page(0)):
output_file = "image_" + str(i) + ".jpg"
with open(output_file, "wb") as image_file_handle:
img.save(image_file_handle)
You can obtain pText either on GitHub, or using PyPi
There are a ton more examples, check them out to find out more about working with images.

Is there a way using librosa's waveplot to store the coordinates of the graph rather than show the image of the waveplot?

I am working on an audio project where I am using Librosa and have the following code from an example online. Rather than opening up an image with a graph of the amplitude versus time, I want to be able to store the coordinates that make up the graph in an array. I have tried a lot of different examples found on stackoverflow as well as other websites with no luck. I am relatively new to python and this is my first question on stackoverflow so please be kind.
import librosa.display
import matplotlib.pyplot as plt
from IPython.display import display, Audio
filename = 'queen2.mp3'
samples, sampleRate = librosa.load(filename)
display(Audio(filename))
plt.figure(figsize=(12, 4))
librosa.display.waveplot(y, sr=None, max_points=200)
plt.show()
librosa is open-source (under the ISC license), so you can look at the code to see how it does this. The documentation for functions has a handy [source] link which takes you do the code. For librosa.display.waveplot you will see that it calls a function __envelope() to compute the envelope. Presumably it is these coordinates you are after.
hop_length = 1
y = __envelope(y, hop_length)
y_top = y[0]
y_bottom = -y[-1]
import numpy as np
def __envelope(x, hop):
'''Compute the max-envelope of non-overlapping frames of x at length hop
x is assumed to be multi-channel, of shape (n_channels, n_samples).
'''
x_frame = np.abs(util.frame(x, frame_length=hop, hop_length=hop))
return x_frame.max(axis=1)

'numpy.ndarray' object has no attribute 'write'

I am writing a python code to calculate the background of an astronomical image of globular cluster M15 (M15 reduced). My code can calculate the background and plot it using plt.imshow(). To save the background subtracted image I have to convert it to a str from a numpy.nparray. I have tried many things including the np.array2string used here. The file just stays as an array, which can't be saved as I need it to save as a .fits file. Any ideas how to get this to a str?
The code:
#sigma clip is the number of standard deviations from centre value that value can be before being rejected
sigma_clip = SigmaClip(sigma=2.)
#used to estimate the background in each of the meshes
bkg_estimator = MedianBackground()
#define path for reading in images
M15red_path = Path('.', 'ObservingData/M15normalised/')
M15red_images = ccdp.ImageFileCollection(M15red_path)
M15reduced = M15red_images.files_filtered(imagetyp='Light Frame', include_path=True)
M15backsub_path = Path('.', 'ObservingData/M15backsub/')
for n in range (0,59):
bkg = Background2D(CCDData.read(M15reduced[n]).data, box_size=(20,20),
filter_size=(3, 3),
edge_method='pad',
sigma_clip=sigma_clip,
bkg_estimator=bkg_estimator)
M15subback = CCDData.read(M15reduced[n]).data - bkg.background
np.array2string(M15subback)
#M15subback.write(M15backsub_path / 'M15backsub{}.fits'.format(n))
print(type(M15subback[1]))
You could try using [numpy.save][1] (but it saves a '.npy' file). In your case,
import numpy as np
...
for n in range (0,59):
...
np.save('M15backsub{}.npy'.format(n), M15backsub)
Since you need to store a numpy array, this should work.

Vast difference in cv2 imshow vs matplotlib imshow?

I am currently working on a program that requires me to read DICOM files and display them correctly. After extracting the pixel array from the DICOM file, I ran it through both the imshow function from matplotlib and cv2. To my surprise they both yield vastly different images. One has color while the other has no, and one shows more detail than the other. Im confused as to why this is happening. I found Difference between plt.show and cv2.imshow? and tried converting the pixels to BRG instead of RGB what cv2 uses but this changes nothing. I am wondering why it is that these 2 frameworks show the same pixel buffer so differently. below is my code and an image to show the outcomes
import cv2
import os
import pydicom
import numpy as np
import matplotlib.pyplot as plt
inputdir = 'datasets/dicom/98890234/20030505/CT/CT2/'
outdir = 'datasets/dicom/pngs/'
test_list = [ f for f in os.listdir(inputdir)]
for f in test_list[:1]: # remove "[:10]" to convert all images
ds = pydicom.dcmread(inputdir + f)
img = np.array(ds.pixel_array, dtype = np.uint8) # get image array
rows,cols = img.shape
cannyImg = cv2.Canny(img, cols, rows)
cv2.imshow('thing',cv2.cvtColor(img, cv2.COLOR_BRG2RBG))
cv2.imshow('thingCanny', cannyImg)
plt.imshow(ds.pixel_array)
plt.show()
cv2.waitKey()
Using the cmap parameter with imshow() might solve the issue. Try this:
plt.imshow(arr, cmap='gray', vmin=0, vmax=255)
Refer to the docs for more info.
Not an answer but too long for a comment. I think the root cause of your problems is in the initialization of the array already:
img = np.array(ds.pixel_array, dtype = np.uint8)
uint8 is presumably not what you have in the DICOM file. First because it looks like a CT image which is usually stored with 10+ bpp and second because the artifacts you are facing look very familiar to me. These kind of artifacts (dense bones displayed in black, gradient effects) usually occur if >8 bit pixeldata is interpreted as 8bit.
BTW: To me, both renderings look obviously incorrect.
Sorry for not being a python expert and just being able to tell what is wrong but unable to tell how to get it right.

How can I write plot title and axis titles with matplotlib?

I developed a python script that plots data from netcdf files. The problem is that I try to modify the title of the plot ( and in other cases I also tried to change x axis title with ax.set_xlabel('etc') ) but python seems not answering.
The data are extracted using xarray and then are plotted using matplotlib.
This is my code:
from os.path import expanduser
home = expanduser("~") # Get users home directory
file = home + '/Desktop/Tesi/Triennial_EOFs/' # Adjust if necessary
path = file + 'normevectortime1905_1.nc'
mask = xr.open_dataset(path, decode_times=False) #extract variables in xarray from .nc file
in_variable='msl'
var = mask[in_variable] #variable to study
ax = plt.subplot(1,1,1, projection=proj)
ax.set_title('PLOT')
ax.set_xlabel('x axes_test')
ax.coastlines(resolution='50m',linewidth=0.4)
var[0,:,:].plot.contourf(transform=crs.PlateCarree(),levels=20)
plt.show()
This is my output
Moreover I never explicitly written code lines for the colorbar or the text related to the variable field near the colorbar. And I never even wrote instructions for written time on the top of the plot.

Resources