So explained briefly I have a folder where I put some images into. The name of the images are integers, so for example I could have 5 images with the names 567.jpg, 568.jpg, 569.jpg, 570.jpg, and 571.jpg. The integer numbers are random, however, they always come in a sequence like above, i.e. increasing by one for every image.
So what I want to do is to go through the images in this folder and look at the image size. If the width of an image is under 600px (as an example) I want to delete this image and move on to the next image. Now, if this image is then above 600px it should be renamed such as it follows the sequence.
So in principle what should happen is:
345.jpg --> Over 600px --> Nothing happens
346-jpg --> Under 600px --> Gets deleted
347.jph --> Over 600px --> Gets renamed to 346.jpg (to follow the 1 step sequence)
And so on...
I have tried with the following code:
import os
from PIL import Image
img_dir_path = "\"
pic_list = range(567,572,1)
for image in pic_list:
img = Image.open("{}/{}.jpg".format(img_dir_path, image))
if img.size[0] < 600:
os.remove("{}/{}.jpg".format(img_dir_path, image))
else:
if os.path.isfile("{}/{}.jpg".format(img_dir_path, int(image)-1)) == False:
os.rename('{}/{}.jpg'.format(img_dir_path, int(image)), '{}/{}.jpg'.format(img_dir_path, int(image)-1))
else:
print "No worries"
However, when doing so I get the follow error:
WindowsError: [Error 32] The process cannot access the file because it is being used by another process
For the rename process that it...
I know this is some sloppy code, but I'm not a Python expert yet, so I usually just make it work first, and then tweak.
In addition, another problem that arises is that when checking if the entry before the true first entry exists / is false, it always is false now since there of course is nothing before the first image. Therefore, the image with the first name in the list should of course not be renamed. However, since I couldn't even get this to work, I wasn't going to try to fix that.
Do close the image which is opened before renaming img = Image.open("{}/{}.jpg".format(img_dir_path, image))
Image.close()
before rename
Related
The following code is part of my code for a tf graph to read images. When I use this code to iterate through the data, the program gets stuck in tf.io.read_file(path) after a few hundred images forever and doesn't do anything. More specifically, the code even can't be paused and I had to restart the session every time.
#tf.function()
def read_image(path):
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image)
return image
...
div8k_list=[os.path.join(div8k_save_path, x) for x in os.listdir(div8k_save_path)]
train_path = tf.data.Dataset.from_tensor_slices(div8k_list)
train_images = train_path.map(read_image, num_parallel_calls=tf.data.AUTOTUNE)
I first suspected that there were a few corrupted images or wrong paths in the data that were causing this problem and tested the following code.
for path in train_path:
print(path)
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image)
Surprisingly, there was no common characteristic of the image path the loop was stuck. And it was not a problem of the image because the loop was once stuck at 1056.png but when I explicitly loaded 1056.png, there was no problem.
What could be the cause of this problem?
edit: to summarize, the program is stuck at read_image forever, while I couldn't find a problem in the dataset.
My dataset is the DIV8K dataset and I am running in COLAB.
EDIT The function that is slowing my code is decode_jpeg, because the following definition of read_image worked multiple times.
#tf.function()
def read_image(path):
image = tf.io.read_file(path)
image = tf.image.decode_jpeg(image)
return image
As mentioned in the comment, try the following function to decode the image file as it can handle mixed extension file format (jpg, png etc), ref.
tf.io.decode_image(image, expand_animations = False)
However, decode_jpeg should also able to handle the .png file format now. Without the image file, it's hard to break down what's causing to prevent this. Most probably the file is somehow corrupted or not the valid extension for the decode_jpeg, though it's named that way, check this solution.
In my python flask program hosted on Ubuntu using Apache2, the program I wrote usually is able to use imread to compress and process an image. The code now is not being able to access the image even though the file path are correct and it is an existing file and does not return any error message. This seems to occur with any type of image not depending on the type of file and the code sometimes returns a none type is not subscript able if that is related to this issue. Thanks for any help in advance! The code:
img = cv2.imread(file_path)
height, width, _ = img.shape
roi = img[0: height, 0: width]
_, compressedimage = cv2.imencode(".jpg", roi, [1, 90])
file_bytes = io.BytesIO(compressedimage)
code sometimes returns a none type
It looks to me like the file path you are supplying might be incorrect. I am saying this because cv2.imread does not throw an error for a non-existent file path:
img = cv2.imread("/non/existent/image.jpeg")
Rather it returns None:
img is None
(returns True). Your code would then fail on img.shape line. So you could either check that the file path is correct before supplying to cv2.imread:
assert os.path.isfile(file_path)
or you could assert img is not None after doing the imread and before going further.
EDIT:
I see that you are claiming that you have checked that the file path is correct and the file exists. But then you are yourself saying
the code sometimes returns a none type is not subscript able
This is because of img[0: height, 0: width] where you are trying to index/subscript None.
You can check that if you type None[0], you get the same error TypeError: 'NoneType' object is not subscriptable. So I still feel that the image path is not correct or it is not a valid image file (has some other extension than the ones listed here). In both cases you get a None on imread.
Since the code snippet you've provided is a part of a larger app, the problem could be somewhere else such that sometime the file path is valid and sometime it is not? I am only guessing at this point.
You can't expect cv2.imshow() to work inside flask or apache.
When apache starts it generally switches user to a user and group called www so it doesn't have the same environment (PATH, HOME DISPLAY and other variables) as when you run something from your Terminal sitting in front of your screen.
Nor does the www user even have the same Python modules installed if you added them to your own user.
It also doesn't have a tty where it could apply cv2.waitKey() to tell if you had pressed a key - to quit, for example.
It also doesn't have permission to draw on your screen - or even know who you are or which one of the potentially many attached screens/sessions you are sitting at.
Maybe consider looking at the logging module to debug/monitor your script and log the image path and its file size prior to cv2.imread() and its shape and dtype afterwards.
I had the same issue.
The solution was to "clean" the path.
I had spaces and "+" in the filepath, and by replacing both with "_" the files are now properly read by cv2.imread().
I am having issues with a function that creates JPG images given a binary string. The program saves two images in quick succession, the first is ~300kb and the second is a cropped version of the same image, around ~30kb
The first (larger) image always saves correctly, however the second image sometimes (Maybe 1 in 4) gets cut off half way, with the lower part of the image being flat grey. Opening the image in notepad++ , it looks like the data just abruptly stops being written
The function that creates the images:
def writeImage(imageData, decoded, imageNumber, config):
if imageNumber == 1:
imageSavePath = image1name
elif imageNumber == 2:
imageSavePath = image2name
print(imageSavePath)
file = open(imageSavePath, 'w+b')
file.write(imageData)
file.close
https://i.imgur.com/T4WSOEX.jpg
This is an example of how the images turn out, the amount that is cut off varies image to image
It sounds like your file isn't being flushed before closing. This should happen automatically when you close it. Your code appears to be missing the () for the close call, e.g. it should be
file.close()
The more pythonic way of handling the file object though is to use a with statement as a context manager. So the code would look like this
def writeImage(imageData, decoded, imageNumber, config):
if imageNumber == 1:
imageSavePath = image1name
elif imageNumber == 2:
imageSavePath = image2name
print(imageSavePath)
with open(imageSavePath, 'w+b') as file:
file.write(imageData)
The file will automatically be closed when you are done with executing the statements nested in the with. This ensures you don't forget to close it and leak the file descriptor.
I am trying to get the Python 2.7 PIL Library to work with JPEG images that are only available as a stream coming from a HDD image and are not complete.
I have set the option:
ImageFile.LOAD_TRUNCATED_IMAGES = True
And load the stream as far as it is available (or better said: as far as I am 100% sure that this data is still a image, not some other file type). I have tested different things and as far as I can tell (for JPEGs) PIL only accepts it as a valid JPEG Image if it finds the 0xFFDA (Start of Scan Marker). This is a short example of how I load the data:
from PIL import Image
from StringIO import StringIO
ImageFile.LOAD_TRUNCATED_IMAGES = True
with open("/path/to/image.raw", 'rb') as fp:
fp.seek("""jump to position in image where JPEG starts""")
data = fp.read("""number of bytes I know that those belong to that jpeg""")
img = Image.open(StringIO(data)) # This would throw exception if the data does
# not contain the 0xffda marker
pixel = img.load() # Would throw exception if LOAD_TRUNCATED_IMAGES = false
height,width = img.size
for i in range(height):
for j in range(width):
print pixel[i,j]
On the very last line I expected (or hoped) to see at least the read pixel data to be displayed. But for every pixel it returns (0,0,0).
The Question: Is what I am trying here not possible with PIL?
Some weeks ago I tried the same with a image file I truncated myself, simply by cutting data from it with an editor. It worked for the pixel-data that was available. As soon as it reached a pixel that I cut off, the program threw an exception (I will try this again later today to make sure that I am not remembering wrong).
If somebody is wondering why I am doing this: I need to make sure that the image/picture inside that hdd image is in consecutive blocks/clusters and is not fragmented. To make sure of this I wanted to use pixel matching.
EDIT:
I have tried it again and this is what I have seen.
I opened a truncated image in GIMP and it showed me a few pixel lines in the upper part, but PIL was not able to at least give me the RGB values of those pixels. It always returns (0,0,0).
I made the image slightly bigger such that the lower 4/5 of the image was not visible, but that was enough for PIL to show me the RGB values that were available. Everything else was (0,0,0).
I am still not 100% sure whether PIL can show me the RGB values, even if only view pixel-data is available.
I would try it with an uncompressed format like TGA. JPG being a compressed format may not make any sense to extract pixels from an incomplete image. JPEG actually stores the parameters for equations that describe the image, not pixel values. When you query a JPEG for a pixel value it evaluates the equations at that point and returns the result.
I have the same problem with Pillow==9.2.0
Let's downgrade to Pillow==8.3.2 and it works.
I don't really know about streaming, but I think that you simply cannot access rgb value the way you do.
Try:
rgb_im = img.convert('RGB')
r, g, b = rgb_im.getpixel((i, j))
I'm trying to convert images taken from a capture (webcam) and do some processing on them with OpenCV, but I'm having a difficult time..
When trying to convert the image to grayscale, the program crashes. (Python.exe has stopped working)
Here is the main snippet of my code:
newFrameImageGS = cv.CreateImage ((320, 240), cv.IPL_DEPTH_8U, 1)
for i in range(0,5):
newFrameImage = cv.QueryFrame(ps3eye)
cv.CvtColor(newFrameImage,newFrameImageGS,cv.CV_BGR2GRAY)
golfSwing.append(newFrameImageGS)
When I try using cvConvertScale I get the assertion error:
src.size() == dst.size() && src.channels() == dst.channels()
which makes sense, but I'm pretty confused on how to go about converting the input images of my web cam into images that can be used by functions like cvUpdateMotionHistory() and cvCalcOpticalFlowLK()
Any ideas? Thanks.
UPDATE:
I converted the image to grayscale manually with this:
for row in range(0,newFrameImage.height):
for col in range(0,newFrameImage.width):
newFrameImageGS[row,col] = (newFrameImage8U[row,col][0] * 0.114 + # B
newFrameImage8U[row,col][1] * 0.587 + # G
newFrameImage8U[row,col][2] * 0.299) # R
But this takes quite a while.. and i still can't figure out why cvCvtColor is causing the program to crash.
For some reason, CvtColor caused the program to crash when the image depths where 8 bit. When I converted them to 32 bit, the program no longer crashed and everything seemed to work OK. I have no idea why this is, but at least it works now.
newFrameImage = cv.QueryFrame(ps3eye)
newFrameImage32F = cv.CreateImage((320, 240), cv.IPL_DEPTH_32F, 3)
cv.ConvertScale(newFrameImage,newFrameImage32F)
newFrameImageGS_32F = cv.CreateImage ((320,240), cv.IPL_DEPTH_32F, 1)
cv.CvtColor(newFrameImage32F,newFrameImageGS_32F,cv.CV_RGB2GRAY)
newFrameImageGS = cv.CreateImage ((320,240), cv.IPL_DEPTH_8U, 1)
cv.ConvertScale(newFrameImageGS_32F,newFrameImageGS)
There is a common mistake here:
You're creating a single image in the newFrameImageGS variable before the loop, then overwrite its contents in the loop, which is then appended to a list. The result will not be what you would expect. The list will contain five references to the same image instance at the end, since only the object reference is appended to the list, no copy of the object made this way. This image will contain the very last frame, so you get five of that frame as a result, which is not what you want, I guess. Please review the Python tutorial if it is not clear for you. You can solve this by moving the first line of the above code into the body of the for loop.
Another possibilities if fixing the above would not help you:
The CvtColor function seems to be the correct one for conversion to grayscale, since it can convert to a different number of channels.
According to this manual the CvtColor function requires a destination image of the same data type as the source. Please double check that newFrameImage is a IPL_DEPTH_8U image.