How to read image files from a Camera (Nikon D5600) with Python - python

Forgive me if I've left anything out or goofed up formatting conventions; this is my first time posting on this sort of forum.
So I've got a Nikon D5600 that I'm using as part of an (extremely basic) image analysis setup. I'd like to be able to use images from it without having to manually transfer the files over each time I run a test, but I've had some trouble getting access to the files.
To be clear, I don't want to capture screenshots of a video; I understand that this is possible, but the resolution is about 1/3 smaller in video, which is a bit of an issue for my application.
So, when I was 6 hours more naive, I plugged in the camera via USB to my (Windows 10) desktop, tried calling the image using the exact (well, I did change the slashes out) file path windows gave me in the properties screen:
img = cv2.imread("This PC/D5600/Removable storage/DCIM/314D5600/CFW_0031.jpg")
That didn't work.
I checked that the command I was using wasn't the issue by copying the picture to another drive:
img = cv2.imread("D:/CFW_0031.jpg")
That worked.
So I think, and think is a bold claim here, that it's something to do with the "This PC" bit of the path. I've read some old (circa 2009) posts about MTP and such things, but I'm honestly not sure if that's even what this camera uses, or how to get started with that if it is in fact the correct protocol.
I've also tried using pygrabber (I believe it's a wrapper of direct show, though my terminology may be wrong) to control the camera via python, but that also didn't work, although I did manage to control my webcam, which was interesting.
Finally, I attempted to set the assign a letter drive to the camera, but found that the camera wasn't in the manager's list of discs. It's entirely possible I just did this method wrong, but I don't quite see how.
Edit regarding comment from Cristoph
-I just need to be able to use the image files in python, probably with opencv. I suppose that counts as reading them?
-I've attached a screenshot of what the "This PC" location looks like in the file explorer. The camera shows up under devices and drives, but doesn't have a drive letter.

Related

Export a geoTIFF file from jupyter notebook to google drive but nothing appears in my google drive

After having searched for a long time for a solution to my problem without succeeding, I'd like to ask you my question here.
I have a python code that creates a geoTIFF file from google earth engine data. I'm running it on jupyter notebook and I want to export the geoTIFF to my google drive.
The code works without error and a shapefile (shp) is embedded as input.
The problem is that nothing appears on my drive, the folder "GEE" that it creates is well created, but it is empty.
Here is the export part of the code:
task = ee.batch.Export.image.toDrive(image=bare1.clip(aoi),
scale=10,
region=aoi.getInfo()['coordinates'],
fileFormat='GeoTIFF',
description='Active',
folder='GEE',
maxPixels=1e9)
task.start()
You should also know that I am a beginner in python :)
Do you have an idea for a solution? Do not hesitate to ask me for more details.
Thanks :)
First: Have you checked the code editor (https://code.earthengine.google.com/) to see if there has been an error message that accounts for the lack of export, or if the file is actually being deposited in a different place? One note about the 'folder' parameter, is that (in my understanding) it doesn't create a folder necessily, but instead is just telling GEE to deposit your image in the most recently created folder of the same name, which could be anywhere in your Drive.
Next, have you definitely mounted your Google Drive? I assume so, if the GEE folder is working, but just to be sure you can always run:
from google.colab import drive
drive.mount('/content/drive')
Next, I have found that when I am exporting an image, I need to convert it to double for correct export. So in your case, this would be changing the first line to (adding the .toDouble())
task = ee.batch.Export.image.toDrive(image=bare1.clip(aoi).toDouble())
If that doesn't work: Have you tried exporting other images with this same code? (Ie replacing bare1 with another image that you know works, like ee.Image(1) which makes a blank image where every pixel is the value 1?
Happy to take another look if none of this helps!
The task console in the GEE code editor should give a description of the export error. Exports are finicky with a number of causes for error. A good first place to check is that you didn't exceed the maximum pixels. You can deal with max pixel errors by reducing the number of bands in your image to only include those that you need, or increasing the maxpixel parameter in your export task. Sometimes the following dictionary style formatting works for me although it's not clear why:
task = ee.batch.Export.image.toDrive(**{
'image':bare1.clip(aoi),
'scale':10,
'region': aoi.getInfo()['coordinates'],
'fileFormat':'GeoTIFF',
'description':'Active',
'folder':'GEE',
'maxPixels':1e9
})
task.start()

Is there a way to review past error messages?

I have a Python script that I use through Spyder to combine video files into one. I've used it quite a few times before. I do make minor changes to it now and then, but nothing that should have cause a major malfunction. It does however hog most of my machine's resources. Anyway, its supposed to iterate through a ton of files and write several new video files, and just now after it got through making 1 video and started on the next, it hung for a second, and briefly threw an error that said something along the lines of not being able to read the first frame of one of my input files, and then all my screens went black, and I had to hard reboot. I have no idea which file it threw the error on, or if that was even the actual cause, there are hundreds of files it goes through. Is there a way of finding it?
The past error messages are stored if the logger is activated. Find the log file location in the system. If you are using linux then it might be in the home folder hidden somewhere. In windows you can find it in C drive system folder.

Capturing and manipulating a webcam feed and exposing it as a "virtual webcam" - in Python, on Windows

The final goal would be to capture the regular webcam feed, manipulate it in some way (blur face, replace background, ...) and then output the result in some way so that the manipulated feed can be chosen as input for whatever application expects a webcam (Discord, Teams, ...).
I am working on a Windows machine and would prefer to do this in Python. This combination has me lost, at the moment.
capturing and manipulating is easy with https://pypi.org/project/opencv-python/
the exposing the feed step seems overly complicated
Apparently, on Linux there are Python libraries just offering that functionality, but they do not work on Windows. Everything that sounded like it could hint towards a good solution went directly into C++ country. There are programs which basically do what I want, e.g. webcamoid (https://webcamoid.github.io/) and I could hack together a solution which captures and processes the feed via Python, then uses webcamoid to record the output and feed it into a virtual webcam. But I'd much prefer to do the whole thing in one.
I have been searching around a bit and found these questions on stackoverflow on the topic:
Using OpenCV Output as Webcam (uses C++ but also gives a Python solution - however, pyfakewebcam does not work on Windows)
How do I stream to a new video source? (not really answered, just links to other question)
How to simulate a webcam device (more C++ hints, links to msdn's Writing a Custom Media Source)
Artificial webcam on windows (basically what I want, but in C++ again)
Writing a virtual webcam? (more explanation on how this might work in C++)
I am getting the strong impression that I need C++ for this or have to work on Linux. However, lacking both a Linux machine and any setup as well as experience in programming in C++, this seems like a large amount of work for the "toy project" this was supposed to be. But maybe I am just missing an obvious library or functionality somewhere?
Hence, the question is: Is there a way to expose a "webcam" stream via Python on Windows?
And, one last idea: What if I used a docker container with a Linux Python environment to implement the functionality I want. Could that container then stream a "virtual webcam" to the host?
You can do this by using pyvirtualcam
First, you need to install it using pip
pip install pyvirtualcam
Then go to This Link and download the zip file from the latest release
Unzip and navigate to \bin\[your computer's bittedness]
Open Command Prompt in that directory and type
regsvr32 /n /i:1 "obs-virtualsource.dll"
This will register a fake camera to your computer
and if you want to unregister the camera then run this command:
regsvr32 /u "obs-virtualsource.dll"
Now you can send frames to the camera using pyvirtualcam
This is a sample:
import pyvirtualcam
import numpy as np
with pyvirtualcam.Camera(width=1280, height=720, fps=30) as cam:
while True:
frame = np.zeros((cam.height, cam.width, 4), np.uint8) # RGBA
frame[:,:,:3] = cam.frames_sent % 255 # grayscale animation
frame[:,:,3] = 255
cam.send(frame)
cam.sleep_until_next_frame()

Extremely new user to Python. "No module named request" error while trying code to detect image subdomains in a website to extract them to a folder

I may sound rather uninformed writing this, and unfortunately, my current issue may require a very articulate answer to fix. Therefore, I will try to be specific as possible as to ensure that my problem can be concisely understood.
My apologizes for that- as this Python code was merely obtained from a friend of mine who wrote it for me in order to complete a certain task. I myself had had extremely minimal programming knowledge.
Essentially, I am running Python 3.6 on a Mac. I am trying to work out a code that allows Python to scan through a bulk of a particular website's potentially existent subdomains in order to find possibly-existent JPG images files contained within said subdomains, and download any and all of the resulting found files to a distinct folder on my Desktop.
The Setup-
The code itself, named "download.py" on my computer, is written as follows:
import urllib.request
start = int(input("Start range:100000"))
stop = int(input("End range:199999"))
for i in range(start, stop + 1):
filename = str(i).rjust(6, '0') + ".jpg"
url = "http://website.com/Image_" + filename
urllib.request.urlretrieve(url, filename)
print(url)
(Note that the words "website" and "Image" have been substituted for the actual text included in my code).
Before I proceed, perhaps some explanation would be necessary.
Basically, the website in question contains several subdomains that include .JPG images, however, the majority of the exact URLs that allow the user to access these sub-domains are unknown and are a hidden component of the internal website itself. The format is "website.com/Image_xxxxxx.jpg", wherein x indicates a particular digit, and there are 6 total numerical digits by which only when combined to make a valid code pertain to each of the existent images on the site.
So as you can see, I have calibrated the code so that Python will initially search through number values in the aforementioned URL format from 100000 to 199999, and upon discovering any .JPG images attributed to any of the thousands of link combinations, will directly download all existent uncovered images to a specific folder that resides within my Desktop. The aim would be to start from that specific portion of number values, and upon running the code and fetching any images (or not), continually renumbering the code to work my way through all of the possible 6-digit combos until the operation is ultimately a success.
(Possible Side-Issue- Although I am fairly confident that my friend's code is written in a manner so that Python will only download .JPG files to my computer from images that actually do exist on that particular URL, rather than swarming my folder with blank/bare files from every single one of URL attempts regardless of whether that URL happens to be successful or not, I am admittedly not completely certain. If the latter is the case, informing me of a more suitable edit to my code would be tremendously appreciated.)
The Execution-
Right off the bat, the code experienced a large error. I'll list through the series of steps that led to the creation of said error.
#1- Of course, I first copy-pasted the code into a text document, and saved it as "download.py". I saved it inside of a folder named "Images" where I sought the images to be directly downloaded to. I used BBEdit.
#2- I proceeded, in Terminal, to input the commands "cd Desktop/Images" (to account for the file being held within the "Images" folder on my Desktop), followed by the command "Python download.py" (to actually run the code).
As you can see, the error which I obtained following my attempt to run the code was the ImportError: No module named request. Despite me guessing that the answer to solving this is simple, I can legitimately say I have got such minimal knowledge regarding Python that I've absolutely no idea how to solve this.
Hint: Prior to making the download.py file, the folder, and typing the Terminal code the only interactions I made with Python were downloading the program (3.6) and placing it in my toolbar. I'm not even quite sure if I am required to create any additional scripts/text files, or make any additional downloads before a script like this would work and successfully download the resulting images into my "Images" folder as is my desired goal. If I sincerely missed something integral at any point during this long read, hopefully, someone in here can provide a thoroughly detailed explanation as to how to solve my issue.
Finishing statements for those who've managed to stick along this far:
Thank you. I know this is one hell of a read, and I'm getting more tired as I go along. What I hope to get out of this question is
1.) Obviously, what would constitute a direct solution to the "No module named request" Input Error in Terminal. In other words, what I did wrong there or am missing.
2.) Any other helpful information that you know would assist this code, for example, if there is any integral step or condition I've missed or failed to meet that would ultimately cause the entirety of my code to cease to work. If you do see a fault in this, I only ask of you to be specific, as I've not got much experience in the programming world. After all, I know there is a lot of developers out here that are far more informed and experienced than am I. Thanks.
urllib.request is in Python 3 only. When running 'python' on a Mac, you're running Python 2 by default. Try running executing with python3.
python --version
might need to
brew install python3
urllib.request is a Python 3 construct. Most systems run Python 2 as default and this is what you get when you run simply python.
To install Python 3, go to https://brew.sh/ and follow the instructions to install the Hombrew package manager. Then run
brew install python3
python3 download.py

Accessing Video Data with Python

Question
How can I take a small sample of streamed frames, and manipulate them using Python? Are there any available libraries to use, or will I have to code the entire project alone?
Tech Specs
OS: Linux
Connection: CAT-5 Ethernet
Camera: dlink DCS-930L
Introduction
I recently asked a question, but it was closed because of clarity issues.
I am re-posting with many more details, and if it is still not clear, feel free to edit or add comments.
Background
I have a dlink DCS-930L camera which is directly connected to my Linux computer with a direct cat5 connection. I assigned it to a static IP adress, and everything works great.
When I open a web-browser, and connect to this static IP address (e.g. log into 192.168.0.20), the camera just works correctly in real time.
I did this was to verify that my camera was working, and that I was able to establish the Ethernet connection correctly.
Now, what I need to do some image processing on the video frames that I receive over the Ethernet from the camera.
I don't want to use the web-browser anymore as a means of display, and instead, I want to use Python to read the frames.
In other words, let's say that the camera produces 30 frames/second, and each frame has a certain size (e.g 1920x1080 pixels).
All I want to do is to start reading these frames in by Python. I don't mind if I am missing frames and if I am processing it slowly. Even if I am able to process one frame over a few seconds, I am still okay with that.
Since video is a collection of images (in this case 30 images per second), I want to be able to read these images using Python, and then be able to do whatever processing that I need to do on these images.
If I had these images saved on the computer, I would open these images with Python, and start to manipulate them. But, since in this case, the images are in fact being streamed, I just want to know how can I sample them (maybe one every few second), and do some manipulation using Python?
Please let me know if my question is still unclear, and I will try to clarify it as much as I can.
Thanks,
--Rudy
According to the manual, the camera serves video through a java applet, so that is will bedifficult to access through python without understanding that server protocol.
However, it does have an option to push images to at ftp server (page 34), so if you install vsftpd on your linux box, you can tell the camera to push images there at maybe as high as 4 fps. There are instructions on setting up vsftpd on ubuntu here, other versions of linux will be similar (I seem to remember fedora needing slightly less setup, but that was years ago).
You will need to enable uploads with the line write_enable=YES in /etc/vsftpd.conf. There are various ways to handle the uploads, the simplest one would be to have it log in with your user account, it will then dump images in your home directory (or a path you specify in the camera config).
You should then be able to open the images normally, ie with PIL.
If you don't want to set up a fileserver, you can try grabbing data directly with urllib2, see this page for how to handle the login. There is some chance by fooling around with fetching data you will be able to extract a video stream, but I think the ftp option will be a lot easier.
I am not familiar with exactly how the dlink DCS-30 works, but I have an earlier-generation model, the dlink DCS-20, and had the same objective, so maybe you can leverage my DCS-20 solution, or parts of it, to solve same for the DCS-30.
The key was just parsing the HTML provided by the built-in web browser access.
External modules requests, PIL, and BeautifulSoup simplify the solution.
Assuming your camera IP is 192.168.0.20, and that you've set up via the webadmin a user login to the camera of user1/pw1, here's the crux of the solution:
from StringIO import StringIO
import requests
from PIL import Image
from bs4 import BeautifulSoup
DCS_IP = "192.168.0.20"
userauth = ('user1', 'pw1')
snapurl = "http://" + DCS_IP + "/top.htm"
r = requests.get(snapurl, auth=userauth)
soup = BeautifulSoup(r.content)
# There are several <img> tags in page, so use border=0 attribute of
# objective <img> to distinguish it
imgtag = soup.find_all("img", attrs={'border':0})
imgsrc = BeautifulSoup(str(imgtag[0])).img['src']
imgurl = "http://" + DCS_IP + "/" + imgsrc
img = requests.get(imgurl, auth=userauth)
i = Image.open(StringIO(img.content))
i.save("snapshot.png")
Once you've retrieved the image (i), you can manipulate further with PIL, or, afterwards, use ffmpeg to, for example, stitch resulting image set into a time-lapse video.
HTH

Categories