notAI-tech / NudeNet

Lightweight nudity detection
https://nudenet.notai.tech/
GNU Affero General Public License v3.0
1.66k stars 335 forks source link

OpenCV's `imread()` fails to read image with non-ASCII filename #149

Closed jdk6979 closed 12 hours ago

jdk6979 commented 2 days ago

Issue: OpenCV's imread() fails to read image with non-ASCII filename

Labels: bug, imread, non-ascii filename

Description:

When trying to read an image file with a non-ASCII filename (e.g., 田.jpg) using OpenCV's imread() function, it returns None and raises an AttributeError when trying to access the image data.

Reproduction steps:

  1. Create an image file with a non-ASCII filename, e.g., 田.jpg.
  2. Write a Python script that uses OpenCV's imread() function to read the image file:

from nudenet import NudeDetector from glob import glob

detector = NudeDetector()

for image_path in glob('jpg') + glob('JPG') + glob('JPEG') + glob('jpeg') + glob('png') + glob('PNG'): print(image_path, "detected parts:" , detector.detect(image_path))

import cv2

image_path = '田.jpg'

def _read_image(image_path, target_size=320): img = cv2.imread(image_path)

Do something with the image, e.g., resize it

img = cv2.resize(img, (target_size, target_size))
return img

img = _read_image(image_path) print(img.shape) # raises AttributeError: 'NoneType' object has no attribute 'shape'

3. Run the script and observe the error.

**Expected behavior:**

OpenCV's `imread()` function should successfully read the image file and return a valid image object.

**Actual behavior:**

The `imread()` function returns `None`, and attempting to access the image data raises an `AttributeError`.

**Workarounds:**

**1. Using Unicode filename**: Adding the `u` prefix to the filename doesn't work:
```python
image_path = u'田.jpg'  # note the 'u' prefix

2. Encoding the filename: Encoding the filename as UTF-8 doesn't work either:

image_path = '田.jpg'.encode('utf-8')

**System information:**

* OpenCV version: 4.10
* nudenet version: 3.2
* Python version: 3.9.1
* Operating system: Windows 10

Any help or guidance on resolving this issue would be greatly appreciated. Thank you.
bedapudi6788 commented 1 day ago

Hi, now you can pass file byte data to the model. like instead of passing .detect(image_path) you can now do .detect(open(image_path, 'rb').read()) this should solve your problem.

jdk6979 commented 22 hours ago

Hi, now you can pass file byte data to the model. like instead of passing .detect(image_path) you can now do .detect(open(image_path, 'rb').read()) this should solve your problem.

while attempting to pass file byte data to the model in the NudeNet.py script with both non-ASCII filenames (e.g., 田.jpg) and ASCII filenames (e.g., 1.jpg). The error message I received is as follows:

Traceback (most recent call last): File "D:\myNudeNet.py", line 348, in detector.detect(image_data) File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 139, in detect preprocessed_image, resize_factor, pad_left, pad_top = _read_image( File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 44, in _read_image img = cv2.imread(image_path) cv2.error: OpenCV(4.10.0) :-1: error: (-5:Bad argument) in function 'imread'

Overload resolution failed:

Can't convert object to 'str' for 'filename' Can't convert object to 'str' for 'filename' Can't convert object to 'str' for 'filename'

The error seems to be caused by the NudeDetector class from the nudenet package expecting a file path as input for the detect method, rather than raw image data. This leads to an argument conversion error when the imread function from OpenCV is invoked within the nudenet package.

To address this error, I have implemented a solution by saving the image data to a temporary file and then passing the file path to the detect method. Here is the updated code snippet that resolves the error:


from nudenet import NudeDetector
import tempfile
import os

pic_path = r'D:\1.jpg'

detector = NudeDetector()

with open(pic_path, 'rb') as f:
    image_data = f.read()

# Save image data to a temporary file
with tempfile.NamedTemporaryFile(delete=False) as temp_file:
    temp_file.write(image_data)
    temp_file_path = temp_file.name

detector.detect(temp_file_path)

# Remove the temporary file
os.unlink(temp_file_path)

However, the code appears cumbersome; could it be improved? Thank you.

bedapudi6788 commented 18 hours ago

while attempting to pass file byte data to the model in the NudeNet.py script with both non-ASCII filenames (e.g., 田.jpg) and ASCII filenames (e.g., 1.jpg). The error message I received is as follows:

Traceback (most recent call last): File "D:\myNudeNet.py", line 348, in detector.detect(image_data) File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 139, in detect preprocessed_image, resize_factor, pad_left, pad_top = _read_image( File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 44, in _read_image img = cv2.imread(image_path) cv2.error: OpenCV(4.10.0) 👎 error: (-5:Bad argument) in function 'imread'

@jdk6979 which version of nudenet are you using? can you do pip install --upgrade nudenet and check again?

or can you reproduce in colab and share the link?

jdk6979 commented 13 hours ago

while attempting to pass file byte data to the model in the NudeNet.py script with both non-ASCII filenames (e.g., 田.jpg) and ASCII filenames (e.g., 1.jpg). The error message I received is as follows:

Traceback (most recent call last): File "D:\myNudeNet.py", line 348, in detector.detect(image_data) File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 139, in detect preprocessed_image, resize_factor, pad_left, pad_top = _read_image( File "C:\ProgramData\Miniconda3\lib\site-packages\nudenet\nudenet.py", line 44, in _read_image img = cv2.imread(image_path) cv2.error: OpenCV(4.10.0) 👎 error: (-5:Bad argument) in function 'imread'

@jdk6979 which version of nudenet are you using? can you do pip install --upgrade nudenet and check again?

or can you reproduce in colab and share the link?

I was using nudenet version 3.2 but found out that a newer version was released two days ago. After running 'pip install --upgrade nudenet' and the non-ASCII filename problem was resolved. Thank you for the suggestion.