I am trying to import a Nikon '.NEF' file into OpenCV. '.NEF' is the file extension for a RAW file format for pictures captured by Nikon cameras. When I open the file in Preview on a Mac, I see that the resolution is 6000 by 4000, and the picture is extremely clear. However, when I import it into OpenCV, I see only 120 by 160 (by 3 for RGB channels) data points, and this leads to a big loss in resolution.
My understanding is that there are 120 by 160 pixels in the NumPy array storing the information about pixels for OpenCV. I tried using -1 for the IMREAD_UNCHANGED flag, but many pixels were left out and image quality was greatly affected.
For your reference, here is my code:
# first Jupyter block
img = cv2.imread('DSC_1051.NEF', -1)
img.shape
Performing img.shape
returns (120, 160, 3).
# second Jupyter block
cv2.namedWindow("Resize", cv2.WINDOW_NORMAL)
cv2.resizeWindow("Resize", 1000, 700)
# Displaying the image
cv2.imshow("Resize", img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Summary of problem:
cv2.imshow()
.My question: how can I use OpenCV to import the desired number of pixels? Is there a specific function that I can use? Am I missing an argument to be passed?
If you want to manipulate RAW images without losing resolution with python you'd need to check on a specialized library like rawpy
import rawpy
with rawpy.imread('filename.NEF') as raw:
raw_image = raw.raw_image
You can check the rawpy documentation for more information
Notes:
Example 1: how to save .NEF as .jpg
Option A: rawpy + Pillow (you need to install Pillow
too)
import rawpy
from PIL import Image
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
Image.fromarray(rgb).save('image.jpg', quality=90, optimize=True)
Option B: rawpy + cv2
import rawpy
import cv2
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imwrite("image.jpg",bgr)
Quality comparison
I test the code with this 19.2mb .NEF image and I got these results:
Method | .jpg output size | Dimensions |
---|---|---|
PIL | 9kb | 320x212 |
cv2 | 14kb | 320x212 |
rawpy + PIL | 1.4mb | 4284 × 2844 |
rawpy + cv2 | 2.5mb | 4284 × 2844 |
Example 2: show .NEF with cv2
import rawpy
import cv2
with rawpy.imread('filename.NEF') as raw:
rgb = raw.postprocess(use_camera_wb=True)
bgr = cv2.cvtColor(rgb, cv2.COLOR_RGB2BGR)
cv2.imshow('image', bgr)
cv2.waitKey(0)
cv2.destroyAllWindows()