Opencv application detection image based on machine learning

import numpy as np
import cv2

'''
Use Python and OpenCV to detect objects in an image and crop them out (frame)
Cropping out the insects in the picture so that most of the irrelevant background is removed can improve the recognition rate. :
step1: Load the image and convert it to a grayscale image (similar to ps-image-decolorization)
	When using png images, an error is reported libpng warning: iCCP: known incorrect sRGB profile
	Although it does not affect the operation of the program, this warning is related to the format of the png image. can be solved by corresponding methods
'''
image = cv2.imread("pic_1.png")
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

'''
step2: Calculate the gradient in the x and y directions with the Sobel operator,
The gradient in the y-direction is then subtracted in the x-direction, and by this subtraction, areas of the image with high-level gradients and low vertical gradients are left.

gradX = cv2.Sobel(gray, ddepth=cv2.cv.CV_32F, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=cv2.cv.CV_32F, dx=0, dy=1, ksize=-1)
报错:AttributeError: module 'cv2' has no attribute 'cv'
'''
gradX = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=1, dy=0, ksize=-1)
gradY = cv2.Sobel(gray, ddepth=cv2.CV_32F, dx=0, dy=1, ksize=-1)

# subtract the y-gradient from the x-gradient
gradient = cv2.subtract(gradX, gradY)
gradient = cv2.convertScaleAbs(gradient)
# print( gradient )
'''
[[  0 255  16 ...  20 255   0]
 [ 94 255   0 ...  40 255 112]
 [ 92 255  58 ...  26 255  92]
 ...
 [255 255 255 ... 255 255 255]
 [204 255 255 ... 148  90 204]
 [  0 118 102 ... 102 118   0]]
'''

# After this step, the resulting image ( pic_2.png )
'''
step3: Remove the noise on the image. First smooth the image with a low pass filter (9 x 9 kernels),
This will help smooth out high frequency noise in the image. The goal of the low pass filter is to reduce the rate of change of the image.
Such as replacing each pixel with the mean of the pixels around it. This smooths out and replaces areas where the intensity varies significantly.

Then, the blurred image is binarized. Any pixels not larger than 90 in the gradient image are set to 0 (black). Otherwise, pixels are set to 255 (white).
'''
# blur and threshold the image
blurred = cv2.blur(gradient, (9, 9))
(_, thresh) = cv2.threshold(blurred, 90, 255, cv2.THRESH_BINARY) # threshold threshold, threshold, critical value
## After this step, the resulting image ( pic_3.png )

'''
step4: In the picture above, we see that there are many black spaces in the body area of ​​the bee,
We'll fill these spaces with white to make it easier for subsequent programs to identify the insect area, which requires some morphological manipulation.
'''
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (25, 25))
closed = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
## After this step, the resulting image ( pic_4.png )
'''
step5: From the above picture, we found that there are some small white spots on the image, which will interfere with the detection of the insect outline later,
to remove them. Morphological erosion and dilation were performed 4 times respectively.
'''
# perform a series of erosions and dilations
closed = cv2.erode(closed, None, iterations=4)
closed = cv2.dilate(closed, None, iterations=4)
## After this step, the resulting image ( pic_5.png )

'''
step6: Find the outline of the insect area.
cv2.findContours() function to find the contour of the detected object.
    The first parameter is the image to be retrieved, which must be a binary image, that is, black and white (not grayscale),
        Therefore, the read image must first be converted to grayscale, and then converted to a binary image.
        In the third step, the binary image has been obtained with the cv2.threshold() function.

    The second parameter indicates the retrieval mode of the contour, there are four kinds:
        cv2.RETR_EXTERNAL means that only the outer contour is detected
        The contour detected by cv2.RETR_LIST does not establish a hierarchical relationship
        cv2.RETR_CCOMP establishes two levels of contours, the upper layer is the outer boundary,
            The inner layer is the boundary information of the inner hole. If there is still a connected object in the inner hole, the boundary of this object is also on the top layer.
        cv2.RETR_TREE builds the outline of a hierarchical tree structure.

    The third parameter is the approximation method of the contour
        cv2.CHAIN_APPROX_NONE stores all contour points, and the pixel position difference of two adjacent points does not exceed 1.
            即max(abs(x1-x2),abs(y2-y1))==1
        cv2.CHAIN_APPROX_SIMPLE compresses elements in the horizontal, vertical, and diagonal directions, and only retains the coordinates of the end point in this direction.
            For example, a rectangular outline only needs 4 points to save the outline information
        The cv2.findContours() function returns two values, one is the contour itself, and the other is the attribute corresponding to each contour.
        The cv2.findContours() function returns the first value is a list, each element in the list is a contour in the image,

Represented by ndarray in numpy. Each ndarray stores the coordinates of each point on the contour.
Sort the list, and the contour with the most points is the contour of the insect you are looking for.

Draw contours on the image through cv2.drawContours in OpenCV.
    The first parameter specifies which image to draw the contour on
    The second argument is the contour itself, which in Python is a list
    The third parameter specifies which contour in the list of contours to draw, if it is -1, all contours in it are drawn
    The fourth parameter is the color of the contour lines
    The fifth parameter is the thickness of the contour lines

cv2.minAreaRect() function:
The main requirement is a rectangle containing the minimum area of ​​the point set. This rectangle can have a deflection angle and can be non-parallel to the border of the image.
'''
get_findContours = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
'''
Use the cv2.findContours() function to find the contours of the detected object.
get_findContours = cv2.findContours(closed.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
Program error: too many values ​​to unpack (expected 2) # ValueError: too many values ​​to unpack (expected 2)
Reason for the error: Due to the version problem, the number of return values ​​of cv2.findContours has changed, calling len(a) to find that the length is 3,
The first one, returns the processed image (new in high version)
The second, the point set of the contour (the old version of the first)
The third, the index of the contour of each layer (the second in the old version)
'''
# print( len(args_) ) # 3
(orgin_obj , cnts, _) = get_findContours
c = sorted(cnts, key=cv2.contourArea, reverse=True)[0]

# compute the rotated bounding box of the largest contour
rect = cv2.minAreaRect(c)
print( 'rect = ' , rect )
'''
rect =  ((500.49993896484375, 298.9999694824219), (1000.9998779296875, 375.99993896484375), -0.0)
'''

'''
When doing a rotated bounding rectangle, box = np.int0(cv2.cv.BoxPoints(rect)) function
报错 AttributeError: module 'cv2' has no attribute 'cv'

Change to box = np.int0(cv2.BoxPoints(rect))
报错 AttributeError: module 'cv2' has no attribute 'BoxPoints'
#Because, the first letter was changed to lowercase cv2.boxPoints(rect)
'''
# help(cv2.boxPoints)
box = np.int0(cv2.boxPoints(rect))

# draw a bounding box arounded the detected barcode and display the image
cv2.drawContours(image, [box], -1, (0, 255, 0), 3)
cv2.imshow("Image", image)
cv2.imwrite("contoursImage2.jpg", image)
cv2.waitKey(0)
## After this step, the resulting image ( pic_6.png )
'''
step7: Crop.
The box saves the coordinates of the four vertices of the green rectangular area. The insect image will be cropped as shown by the red rectangle in the image below.
Find the maximum and minimum of the x, y coordinates of the four vertices. New image height=maxY-minY, width=maxX-minX.
## After this step, the resulting image ( pic_7.png )
'''
print(box)
'''
[[424 439]
 [213 197]
 [403  30]
 [614 272]]
'''
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
print(Xs) # [424, 213, 403, 614]
print(Ys) # [439, 197, 30, 272]

x1 = min(Xs)
x2 = max(Xs)
y1 = min (Ys)
y2 = max(Ys)
hight = y2 - y1
width = x2 - x1
cropImg = image[y1:y1 + hight, x1:x1 + width]
'''
## After this step, the resulting image ( pic_8_last.png )
'''


This example comes from the network. After adding notes and modifying bugs, it runs normally after testing. The original image is as follows:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325447323&siteId=291194637