1, Grayscale
Definition of grayscale
In the R, G, B image model, when R=G=B (when the three color component values are the same), then the color represents a gray color, where the value of R=G=B is called gray value, in the gray image, the gray value can also be called brightness value. Gray value range 0-255
Grayscale method
For a color image, there are four commonly used methods of graying, which are the component method maximum value method average value method weighted average method.
1. component method
This method is the most simple, that is, in the R, G, B three color components, choose any color as the gray value
2. Maximum method
The method is to find out the value of each pixel's R, G, B three color components, then find the color with the largest value, and then take the maximum value as the gray value
f(x,y)=Max{R(x,y),G(x,y),B(x,y)}
f(x,y)=Max\left \{ R(x,y),G(x,y),B(x,y)\right \}
f(x,y)=Max{R(x,y),G(x,y),B(x,y)}
3. Average method
This method is to find the component values of R, G and B, and finally set the gray value as the average value of the three component values.
f(x,y)=R(x,y)+G(x,y)+B(x,y)3
f(x,y)=\frac{R(x,y)+G(x,y)+B(x,y)}{3}
f(x,y)=3R(x,y)+G(x,y)+B(x,y)
4. Weighted average method
Because the sensitivity of the human eye to each color is different, in which the human eye has the highest sensitivity to green and the lowest sensitivity to blue, we can use the weighted average method to calculate the gray value, and the formula is as follows
f(x,y)=aiR(i,j)+biG(i,j)+ciB(i,j)f(x,y)=a_iR(i,j)+b_iG(i,j)+c_iB(i,j)f(x,y)=aiR(i,j)+biG(i,j)+ciB(i,j)
Grayscale application scene
- When a computer recognizes an object through an image, the most important factor is the gradient of the image. With the gradient, we can find the edge of the object and locate the object. However, gradient calculation must use gray-scale image. Color image is very easy to be affected by light and other factors, and there are many changes in the color of similar objects, so color image is difficult to provide some key information
- After the image is grayed, the dimension of the matrix is reduced, so the operation speed will be greatly improved, and the gradient information can be preserved.
2, Algorithm implementation based on python
Because in the process of image graying, it is necessary to scan the image. As for the determination of the value, we can use a single function to get it, so the scanning process is independent, and the acquisition of the value is independent. We use a Values() method alone to get the gray value we need. The parameter is a list with R, G and B values
Method as a whole is very simple, just a few lines of code. Just use all kinds of formulas to calculate the gray value. All that's left is the sweep function
The following is a class for processing BMP image files. The code in the previous section can be integrated to read 8-bit pseudo color and 24 bit true color images
class BmpManager: def __init__(self,fileName): self.f_size=None self.f_width=None self.f_height=None self.f_ofset=None self.f_bitcount=None self.colorTab=None self.Img=None def Parse(self,fileName): f=open(fileName,'rb') file_type=str(f.read(2),encoding='utf-8') assert file_type=='BM',"Wrong file type" file_size_byte = f.read(4) # This can be used to read the size of the file. It needs to read 4 bytes f.seek(f.tell() + 4) # Skip four useless bytes in the middle file_ofset_byte = f.read(4) # Offset to read bitmap data f.seek(f.tell() + 4) # Skip two useless bytes file_wide_byte = f.read(4) # Read width bytes file_height_byte = f.read(4) # Read height bytes f.seek(f.tell() + 2) ## Skip two useless bytes in the middle file_bitcount_byte = f.read(4) # Get the occupation size of each pixel #Here is how to convert the bytes read to the specified type self.f_size,=struct.unpack('l',file_size_byte) self.f_ofset,=struct.unpack('l',file_ofset_byte) self.f_width,=struct.unpack('l',file_wide_byte) self.f_height,=struct.unpack('l',file_height_byte) self.f_bitcount,=struct.unpack('i',file_bitcount_byte) # Determine whether there is a color table if self.f_ofset==1078: self.__256Image__(fileName)#Processing pseudo color image else: self.__24BImage(fileName) #Process true color images def __256Image__(self,f_name): 'Then read the color table' f=open(f_name,'rb') self.colorTab = np.array([],dtype=int) f.seek(54) # Skip file and bitmap headers for i in range(0, 256): b = struct.unpack('B', f.read(1))[0] g = struct.unpack('B', f.read(1))[0] r = struct.unpack('B', f.read(1))[0] alpha = struct.unpack('B', f.read(1))[0] self.colorTab=np.append(self.colorTab,np.array([r,g,b,255])) self.colorTab=self.colorTab.reshape(256,4) 'The following section is for reading BMP Bitmap data area,Store data in numpy array' # Offset the file pointer first f.seek(self.f_ofset) # Because the image is an 8 bit pseudo color image, one pixel takes up one byte, that is, 8 bits img = np.empty(shape=[self.f_height, self.f_width, 4], dtype=int) cout = 0 for y in range(0, self.f_height): for x in range(0, self.f_width): cout = cout + 1 index = struct.unpack('B', f.read(1))[0] img[self.f_height - y - 1, x] = self.colorTab[index] while cout % 4 != 0: f.read(1) cout = cout + 1 self.Img=img def __24BImage(self,f_name): f=open(f_name,'rb') f.seek(self.f_ofset) img=np.empty(shape=[self.f_height,self.f_width,3],dtype=int) cout=0 for y in range(0,self.f_height): for x in range(0,self.f_width): BYTES=f.read(3) x1,x2,x3=struct.unpack('BBB',BYTES) cout=cout+3 img[self.f_height - y - 1, x]=np.array([x3,x2,x1]) while cout%4!=0: cout=cout+1 f.read(1) self.Img=img def getHeight(self): return self.f_height def getWidth(self): return self.f_width def getImage(self): return self.Img def getSize(self): return self.f_size def grayScale(self,method='AVG'): #Next, scan the image for y in range(0,self.f_height): for x in range(0,self.f_width): value=self.Values(method,self.Img[y][x]) self.Img[y][x]=np.array([value,value,value]) def Values(self,methods,v): if methods=='AVG': return np.average(v) if methods=='R': return v[0] if methods=='G': return v[1] if methods=='B': return v[2] if methods=='Max': return np.max(v) if methods=='WAvg': return 0.3*v[0]+0.59*v[1]+0.11*v[2]