Basic Cooking #1 -Open,Save, Resize, Display
OpenCV Open image
Use cv2.imread function to open an image file.import cv2 img = cv2.imread("dog.jpg", cv2.IMREAD_COLOR) height, width, channels = img.shape print("JPG H:%d W:%d, Channel:%d"%(height, width, channels)) #There's no channel value when open with grayscale img = cv2.imread("dog.jpg", cv2.IMREAD_GRAYSCALE) height, width = img.shape print("JPG H:%d W:%d "%(height, width)) img = cv2.imread("linux.png", cv2.IMREAD_COLOR) height, width, channels = img.shape print("PNG 1 H:%d W:%d, Channel:%d"%(height, width, channels)) img = cv2.imread("linux.png", cv2.IMREAD_UNCHANGED) height, width, channels = img.shape print("PNG 2 H:%d W:%d, Channel:%d"%(height, width, channels))
<open.py>
Flags
- cv2.IMREAD_COLOR : BGR format image is opened. So the channel will be 3.
- cv2.IMREAD_GRAYSCALE : only 1 grayscale channel is opened. So the channel informaion is not necessary and there's no channel value in the img.shape.
- cv2.IMREAD_UNCHANGED : Retains the format stored in the image file. If there's an alpha channel in the image, BGRA format image is opened. So the channel will be 4.
root@spypiggy-ubuntu:/usr/local/src/study/python/opencv# python3 open.py JPG H:174 W:290, Channel:3 JPG H:174 W:290 PNG 1 H:395 W:386, Channel:3 PNG 2 H:395 W:386, Channel:4
Be Careful : If you open the image in grayscale mode or convert the color image to grayscale, the shape returns only height and width values because there is only one channel. Therefore, an error occurs when trying to read the channel value.
If you want to open online image, use urllib
import numpy as np import urllib.request import cv2 url = 'http://images.cocodataset.org/val2017/000000439715.jpg' req = urllib.request.urlopen(url) img = np.asarray(bytearray(req.read()), dtype=np.uint8) img = cv2.imdecode(img, cv2.IMREAD_COLOR) height, width, channels = img.shape print("H:%d W:%d, Channel:%d"%(height, width, channels))
PIL Open image
Use PIL open function to open an image file.from PIL import Image img = Image.open("f:\\tmp\\outg.jpg") w, h = img.size print('W:%d H:%d'%(w, h))
<open_pil.py>
root@spypiggy-ubuntu:/usr/local/src/study/python/opencv# python3 open_pil.py W:174 H:290
Be Careful : When using PIL, the size of the image is stored in Image.size. While OpenCV's Mat.shape is stored in the order of height, width and channel, the size of PIL is stored in the order of width and height. And channel information is not stored.
If you want to know the channel information, use Image.mode
from PIL import Image img = Image.open("f:\\tmp\\outg.jpg") w, h = img.size print('W:%d H:%d'%(w, h)) print(img.mode)
The mode values are defined as follows at https://pillow.readthedocs.io/en/5.1.x/handbook/concepts.html#modes.
The
mode
of an image defines the type and depth of a pixel in the image. The current release supports the following standard modes:
1
(1-bit pixels, black and white, stored with one pixel per byte)L
(8-bit pixels, black and white)P
(8-bit pixels, mapped to any other mode using a color palette)RGB
(3x8-bit pixels, true color)RGBA
(4x8-bit pixels, true color with transparency mask)CMYK
(4x8-bit pixels, color separation)YCbCr
(3x8-bit pixels, color video format)
- Note that this refers to the JPEG, and not the ITU-R BT.2020, standard
LAB
(3x8-bit pixels, the L*a*b color space)HSV
(3x8-bit pixels, Hue, Saturation, Value color space)I
(32-bit signed integer pixels)F
(32-bit floating point pixels)
If you want to open online image, use requests
import numpy as np import requests from PIL import Image url = 'http://images.cocodataset.org/val2017/000000439715.jpg' img = Image.open(requests.get(url, stream=True).raw).convert('RGB') w, h = img.size print('W:%d H:%d'%(w, h))
OpenCV Image to numpy vice versa
OpenCV images (Mat) have a numpy array and can be used directly without conversion.import cv2 img = cv2.imread("dog.jpg", cv2.IMREAD_COLOR) print(type(img));
root@spypiggy-ubuntu:/usr/local/src/study/python/opencv# python3 shape.py
<class 'numpy.ndarray'>
Numpy arrays can be used as Mat objects in opencv without conversion.
import cv2
import numpy as np
img = np.zeros((512,512,3),np.uint8) height, width, channels = img.shape
PIL Image to numpy vice versa
PIL uses image channels in the RGB order. However, OpenCV uses an image channel in the BGR order, so you need to change the image format from RGB to BGR if the color image is opened.
from PIL import Image im = Image.open(filename) array = np.asarray(im, dtype="uint8") array = cv2.cvtColor(array, cv2.COLOR_RGB2BGR)
And you can convert numpy array to an PIL image using fromarray function(same as OpenCV).
from PIL import Image im = Image.fromarray(np.uint8(array)) width, height = im.size
OpenCV Pixel Position
Common coordinates in mathematics use the (x, y) format. However, the example below shows that OpenCV has a shape value in the order of height, width, and channel. Therefore, OpenCV has (y, x, channel) coordinates.
import cv2
import numpy as np
img = np.zeros((512,100,3),np.uint8) height, width, channels = img.shape
For example, if you have a png image of 2X2 pixels as shown in the following figure, you will have a shape of (22,24).
And the values of the four pixels are as follows. As the result shows (y, x, c).
import cv2 img = cv2.imread('c:\\lsh\\study\\opencv\\4pixel.png', cv2.IMREAD_UNCHANGED) print(img[0][0]) print(img[1][0]) print(img[0][1]) print(img[1][1])
#### output ####
[255 255 255 0] [255 255 255 255] [ 0 0 0 255] [ 0 216 255 255]
OpenCV Format conversion
Use cv2.cvtColor function to convert an image format.import cv2 img = cv2.imread("linux.png", cv2.IMREAD_UNCHANGED ) height, width, channels = img.shape print("RGBA H:%d W:%d, Channel:%d"%(height, width, channels)); #convert to gray gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) height, width = gray.shape print("GRAY H:%d W:%d"%(height, width)); #remove alpha (you can also use cv2.COLOR_BGRA2RGB) bgr = cv2.cvtColor(img, cv2.COLOR_BGRA2BGR) height, width, channels = bgr.shape print("BGR H:%d W:%d, Channel:%d"%(height, width, channels)); #bgr -> rgb rgb = cv2.cvtColor(bgr, cv2.COLOR_BGR2RGB) height, width, channels = rgb.shape print("RGB H:%d W:%d, Channel:%d"%(height, width, channels));
root@spypiggy-ubuntu:/usr/local/src/study/python/opencv# python3 conv.py RGBA H:395 W:386, Channel:4 GRAY H:395 W:386 BGR H:395 W:386, Channel:3 RGB H:395 W:386, Channel:3
The following values are frequently used for conversion.
- COLOR_BGR2BGRA = 0,
- COLOR_RGB2RGBA = COLOR_BGR2BGRA,
- COLOR_BGRA2BGR = 1,
- COLOR_RGBA2RGB = COLOR_BGRA2BGR,
- COLOR_BGR2RGBA = 2,
- COLOR_RGB2BGRA = COLOR_BGR2RGBA,
- COLOR_RGBA2BGR = 3,
- COLOR_BGRA2RGB = COLOR_RGBA2BGR,
- COLOR_BGR2RGB = 4,
- COLOR_RGB2BGR = COLOR_BGR2RGB,
- COLOR_BGRA2RGBA = 5,
- COLOR_RGBA2BGRA = COLOR_BGRA2RGBA,
- COLOR_BGR2GRAY = 6,
- COLOR_RGB2GRAY = 7,
PIL Format Conversion
Use Image.convert function to convert an image format. For usage, refer to the following document (https://pillow.readthedocs.io/en/stable/reference/Image.html).
Image.
convert
(mode=None, matrix=None, dither=None, palette=0, colors=256)[source] Returns a converted copy of this image. For the “P” mode, this method translates pixels through the palette. If mode is omitted, a mode is chosen so that all information in the image and the palette can be represented without a palette.The current version supports all possible conversions between “L”, “RGB” and “CMYK.” The matrix argument only supports “L” and “RGB”.When translating a color image to greyscale (mode “L”), the library uses the ITU-R 601-2 luma transform:L = R * 299/1000 + G * 587/1000 + B * 114/1000The default method of converting a greyscale (“L”) or “RGB” image into a bilevel (mode “1”) image uses Floyd-Steinberg dither to approximate the original image luminosity levels. If dither is NONE, all values larger than 128 are set to 255 (white), all other values to 0 (black). To use other thresholds, use thepoint()
method.When converting from “RGBA” to “P” without a matrix argument, this passes the operation toquantize()
, and dither and palette are ignored.
Parameters:
- mode – The requested mode. See: Modes.
- matrix – An optional conversion matrix. If given, this should be 4- or 12-tuple containing floating point values.
- dither – Dithering method, used when converting from mode “RGB” to “P” or from “RGB” or “L” to “1”. Available methods are NONE or FLOYDSTEINBERG (default). Note that this is not used when matrix is supplied.
- palette – Palette to use when converting from mode “RGB” to “P”. Available palettes are WEB or ADAPTIVE.
- colors – Number of colors to use for the ADAPTIVE palette. Defaults to 256.
Return type: Returns: The following example converts an RGB image (linearly calibrated according to ITU-R 709, using the D65 luminant) to the CIE XYZ color space:rgb2xyz = ( 0.412453, 0.357580, 0.180423, 0, 0.212671, 0.715160, 0.072169, 0, 0.019334, 0.119193, 0.950227, 0) out = im.convert("RGB", rgb2xyz)
OpenCV Resize
Use cv2.resize function to resize an image file.import cv2 img = cv2.imread('linux.png', cv2.IMREAD_UNCHANGED) height, width, channels = img.shape print("H:%d W:%d, Channel:%d"%(height, width, channels)); img2 = cv2.resize(img, (int(width / 2), int(height / 2))) height, width, channels = img2.shape print("H:%d W:%d, Channel:%d"%(height, width, channels));
root@spypiggy-ubuntu:/usr/local/src/study/python/opencv# python3 resize.py H:395 W:386, Channel:4 H:197 W:193, Channel:4
PIL Resize
Use Image.resize function to resize an image file.img = Image.open('./linux.png') width, height = img.size print("H:%d W:%d"%(height, width)); img2 = img.resize((int(width / 2), int(height / 2))) width, height = img2.size print("H:%d W:%d"%(height, width));
OpenCV Display image
Use cv2.imshow function to display an image file.Tips : If you use a remote ssh shell, use a ssh terminal like MobaXterm which supports X11 forwarding. Then you can view the display image windows.
First parameter is window name, and if there's multi windows, each window name must be different.
cv2.waitKey(time) function waits for keyboard input. If time value is 0, wait forever for keyboard input. If time value is not zero, it waits for time value(ms) and returns.
import cv2 img = cv2.imread("dog.jpg", cv2.IMREAD_COLOR) height, width, channels = img.shape print("JPG H:%d W:%d, Channel:%d"%(height, width, channels)); cv2.imshow('color', img) #There's no channel value when open with grayscale img2 = cv2.imread("dog.jpg", cv2.IMREAD_GRAYSCALE) height, width = img2.shape print("JPG H:%d W:%d "%(height, width)); cv2.imshow('gray', img2) img3 = cv2.imread("linux.png", cv2.IMREAD_COLOR) height, width, channels = img3.shape print("PNG 1 H:%d W:%d, Channel:%d"%(height, width, channels)); cv2.imshow('png1', img3) img4 = cv2.imread("linux.png", cv2.IMREAD_UNCHANGED) height, width, channels = img4.shape print("PNG 2 H:%d W:%d, Channel:%d"%(height, width, channels)); cv2.imshow('png2', img4) cv2.waitKey(0) cv2.destroyAllWindows()
Four image windows open like this.
PIL Display image
Use Image.show function to display an image file.img = Image.open("f:\\tmp\\dog.jpg") width, height = img.size print("H:%d W:%d"%(height, width)); img.show() img2 = Image.open("f:\\tmp\\dog.jpg") img2 = img2.convert('LA') img2.show()
Be Careful : PIL uses the operating system's default image viewer to display images.
Therefore, a new process is created. The show () function is returned only when the newly created image viewer process is terminated. Therefore, like OpenCV, multiple windows are not created at the same time. In the above example, after the first color dog.jpg picture window is opened, the corresponding image viewer program must be closed before the next grayscale dog image is displayed.
OpenCV Save image
Use cv2.imwrite function to save an image file.This code will save 1/4 size of linux.png as small_linux.png.
import cv2 img = cv2.imread('linux.png', cv2.IMREAD_UNCHANGED) height, width, channels = img.shape print("H:%d W:%d, Channel:%d"%(height, width, channels)); img2 = cv2.resize(img, (int(width / 2), int(height / 2))) height, width, channels = img2.shape print("H:%d W:%d, Channel:%d"%(height, width, channels)); cv2.imwrite("./small_linux.png", img2)
PIL Save image
Use Image.save function to save an image file.This code will save 1/4 size of linux.png as small_linux.png.
img = Image.open('./linux.png') width, height = img.size print("H:%d W:%d"%(height, width)); img2 = img.resize((int(width / 2), int(height / 2))) width, height = img2.size print("H:%d W:%d"%(height, width)); img2.save('./small_linux.png')
댓글
댓글 쓰기