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