Use python PIL Read image from library , This method returns a Image object ,Image Object stores the format of the image (jpeg,jpg,ppm etc. ), Size and color mode (RGB), It contains a show() Method to display an image :
# Import PIL library
from PIL import Image
# Use Image Class to read an image
img = Image.open("Image-Progcess/image.png")
# View image information
print(img.format,img.size,img.mode)
# Display images
img.show()You don't need to format an image to read it .
Use Image Objects are written to image files in different formats , You need to specify its format :
# Write image
# Import system library , Provide a method to get the directory
# Import PIL library
from PIL import Image
import os,sys
# Image Object use save Method to store an image file
# Convert file to JPEG
# sys.argv[1:] It's using python file.py [args] Call the python Module parameters [args]
for infile in sys.argv[1:]:
f,e = os.path.splitext(infile)
outfile = f + ".png"
print(outfile)
if infile != outfile:
try:
img = Image.open("image.png")
print(img.size)
with Image.open(outfile) as im:
print(im.size)
im.save(f+'.jpg')
im.save(f+'.ppm')
im.save(f+'.bmp')
except OSError as e:
print('cannot convert',str(e))BMP Format , Also known as Bitmap ( Bitmap ), yes Windows Image file format widely used in the system , Because it can save the data of image pixel domain without any transformation , It becomes what we get RAW An important source of data .
BMP The data of the file is divided into four parts according to the sequence of the beginning of the file header :
A bitmap is represented by an array of bits ,32 Bit and 16 Bits indicate color quality , That is, the number of bits per pixel (1、4、8、15、24、32 or 64) , This number is specified in the file header .
The number of colors of the bitmap is determined by the palette , Only 4,8 Only bit images use palette data ,16,24,32 Bit images do not require palette data , The palette only needs... At most 256 term ( Indexes 0 - 255). The size of the palette depends on the color mode used :2 The color image is 8 byte ;16 Color image bit 64 byte ;256 The color image is 1024 byte .
type
advantage
shortcoming
Application scenarios
Compare the same picture size
BMP
Lossless preservation , The picture is the best , Broad support for
It's too big , It is not conducive to storage and network transmission
57.1MB
GIF
Animation storage format
most 256 color , Poor picture quality
PNG
Almost lossless compression and good quality
High quality
1.4MB
JPG
High compression ratio , Conducive to network transmission
General quality
License plate recognition
425KB
Singular value decomposition is one of the methods of matrix decomposition , It decomposes the matrix into 3 Submatrix , namely U,S,V, among U Is the left eigenvector ,S Is a diagonal matrix of singular values ,V It is called right eigenvector .
Use numpy Of linalg.svd() Method to reconstruct the image SVD matrix .
linalg.svd( matrix ,full_matrices=True,compute_uv=True,hermitian=False)
Parameters :
Use linalg.svd() Method decomposition matrix , See how many linearly independent feature vectors the image has .
# The import module
import requests
import cv2
import numpy as np
import matplotlib.pyplot as plt
# Assign and open images
url = 'https://media.geeksforgeeks.org/wp-content/cdn-uploads/20210401173418/Webp-compressed.jpg'
response = requests.get(url, stream=True)
with open('image.png', 'wb') as f:
f.write(response.content)
img = cv2.imread('image.png')
# Convert images to grayscale to speed up
# Calculation .
gray_image = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Calculation SVD
u, s, v = np.linalg.svd(gray_image, full_matrices=False)
# Check the shape of the matrix
print(f'u.shape:{u.shape},s.shape:{s.shape},v.shape:{v.shape}')The output shape indicates that the image has 3648 Linear independent eigenvectors .
# The import module
import seaborn as sns
var_explained = np.round(s**2/np.sum(s**2), decimals=6)
# Variance explains the top singular vector
print(f'variance Explained by Top 20 singular values:\n{var_explained[0:20]}')
sns.barplot(x=list(range(1, 21)),
y=var_explained[0:20], color="dodgerblue")
plt.title('Variance Explained Graph')
plt.xlabel('Singular Vector', fontsize=16)
plt.ylabel('Variance Explained', fontsize=16)
plt.tight_layout()
plt.show()The variance explanation chart above shows that , about 99.77% The information of is interpreted by the first eigenvector and its corresponding eigenvalue itself .
Using different numbers of singular values to reconstruct the image :
# Draw images with different numbers of singular values
comps = [3648, 1, 5, 10, 15, 20]
plt.figure(figsize=(12, 6))
for i in range(len(comps)):
low_rank = u[:, :comps[i]] @ np.diag(s[:comps[i]]) @ v[:comps[i], :]
if(i == 0):
plt.subplot(2, 3, i+1),
plt.imshow(low_rank, cmap='gray'),
plt.title(f'Actual Image with n_components = {comps[i]}')
else:
plt.subplot(2, 3, i+1),
plt.imshow(low_rank, cmap='gray'),
plt.title(f'n_components = {comps[i]}')The basic idea of erosion is like soil erosion , It erodes the boundaries of the foreground object ( Always try to keep the foreground white ). So what does it do ? The kernel slides through the image ( If in 2D The convolution ). Only if all pixels under the kernel are 1 when , Pixels in the original image (1 or 0) Will be regarded as 1, Otherwise it will be eroded ( Make it zero ).
The corrosion operation is to replace the value of the central pixel covered by the structural element with the minimum value :
import cv2
import numpy as np
img = cv2.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv2.erode(img,kernel,iterations = 1)The expansion operation is to replace the value of the central pixel covered by the structural element with the maximum value :
dilation = cv2.dilate(img,kernel,iterations = 1)
HoughCircles() Function accepts only single channel images , Use... Before using images cv2.cvtColor() Function to get a grayscale image :
# Gray image gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
Circle drawing function using Hoff circle transformation :
# A circle
def drawCircle(image):
# Hoff circle transformation
circles = cv2.HoughCircles(
image,
cv2.HOUGH_GRADIENT,
1,
20,
param1=50,
param2=30,
minRadius=0,
maxRadius=0
)
# Make sure you find at least some circles
output = image.copy()
if circles is not None:
# Put the round (x, y) Coordinates and radii are converted to integers
circles = np.round(circles[0, :]).astype("int")
# loop (x, y) Coordinates and radius of the circle
for (x, y, r) in circles:
# Draw a circle in the output image , Then draw a rectangle
# Corresponding to the center of the circle
cv2.circle(output, (x, y), r, (0, 255, 0), 4)
# Display the output image
cv2.imshow("output", np.hstack([image, output]))
cv2.waitKey(0)1) Using fuzzy gray image and Hough circle transform
img = cv2.imread('Image-Progcess/image1.png')
# Gray image
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Blurred grayscale image
blurred = cv2.medianBlur(gray,5)
# A circle
drawCircle(blurred)2) Using corrosion operation and Hoff circle transformation
erosion = cv2.erode(img,kernel,iterations = 1)
3) Use the expansion operation
dilation = cv2.dilate(img,kernel,iterations = 1)
The on operation is to etch the image first , Then the image is expanded , The disconnect operation can disconnect two objects . Realize object separation .
The close operation uses structural elements to expand the image first and then erode it , It is just the reverse of the open operation , But the closed operation is definitely not the reverse result of the open operation .
The gradient operation of morphology is the difference between the results of image expansion and corrosion :
# Open operation opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel) # Closed operation closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel) # Morphological gradient gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
To detect a circle or any other geometric shape , We first need to detect the edges of objects in the image .
The edges in the image are points with sharp color changes . for example , The edge of the red ball on a white background is a circle . In order to recognize the edge of the image , A common method is to calculate the image gradient .
Find the outline of the image :
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
# Import the required Library
import numpy as np
import imutils
import cv2
# Convert to grayscale image
image = cv2.imread('Image-Progcess/tiaoxingma2.jpg')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
# Use Scharr Operator edge detection method
ddepth = cv2.CV_32F if imutils.is_cv2() else cv2.CV_32F
gradX = cv2.Sobel(gray, ddepth=ddepth, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=ddepth, dx=0, dy=1, ksize=-1)
gradient = cv2.subtract(gradX,gradY)
gradient = cv2.convertScaleAbs(gradient)
# Noise removal
## Blur and thresholding
blurred = cv2.blur(gradient,(9, 9))
(_, thresh) = cv2.threshold(blurred, 231, 255, cv2.THRESH_BINARY)
## Morphological processing
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (21, 7))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
# Determine the detection profile , Draw the detection box
cnts = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]
rect = cv2.minAreaRect(c)
box = cv2.boxPoints(rect) if imutils.is_cv2() else cv2.boxPoints(rect)
box = np.int0(box)
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
cv2.waitKey(0)
cv2.destroyAllWindows()python+OpenCV Check the barcode
OpenCV Image morphological operation in