opencv 这个效果差一点
import cv2
import numpy as np
import os
import time
GAUSSIAN_BLUR_KERNEL_SIZE=(5,5)
GAUSSIAN_BLUR_SIGMA_X=0
CANNY_THRESHOLD1=60
CANNY_THRESHOLD2=250
LEEXING=4
def get_gaussian_blur_image(image):
return cv2.GaussianBlur(image,GAUSSIAN_BLUR_KERNEL_SIZE,GAUSSIAN_BLUR_SIGMA_X)
def get_canny_image(image):
return cv2.Canny(image,CANNY_THRESHOLD1,CANNY_THRESHOLD2)
def get_contours(image):
contours,_=cv2.findContours(image,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
return contours
def lp(imgsss):
img1=cv2.imread(imgsss,0)
x1=cv2.Sobel(img1,cv2.CV_16S,1,0,ksize=-1)
y1=cv2.Sobel(img1,cv2.CV_16S,0,1,ksize=-1)
Scale_absX1=cv2.convertScaleAbs(x1)
Scale_absY1=cv2.convertScaleAbs(y1)
result1=cv2.addWeighted(Scale_absX1,0.5,Scale_absY1,0.5,0)
return result1
def ceshi1(imgsss):
image_raw = cv2.imread(imgsss)
h, w, _ = image_raw.shape
mianji_MIN1 = 15000
mianji_MAX1 = 40000
zhouchang_min = 80
zhouchang_max = 1800
offset_min = 0.5 * image_raw.shape[1]
offset_max = 0.95 * image_raw.shape[1]
result1 = lp(imgsss)
# 高斯去噪
result2 = get_gaussian_blur_image(result1)
# 均值
result3 = cv2.blur(result2, (3, 3))
# 提取輪廓
image_canny = get_canny_image(result3)
# 膨脹
kernel = np.ones((3, 3), np.uint8)
dige_dilate1 = cv2.dilate(image_canny, kernel, iterations=1)
# 中值
median = cv2.medianBlur(dige_dilate1, 5)
contours = get_contours(median)
image = cv2.imread(imgsss)
contour = image.copy()
cv2.drawContours(contour, contours, -1, (0, 255, 0), 2)
count = 0 # 个数
margin = 5 # 裁剪边距
draw_rect = image.copy()
for i, contour in enumerate(contours):
area = cv2.contourArea(contour) # 计算包围形状的面积
zhouchang = cv2.arcLength(contour, True)
x2, y2, w2, h2 = cv2.boundingRect(contour)
if area < mianji_MIN1: # 过滤面积小于15的形状
continue
if area > mianji_MAX1: # 过滤面积小于15的形状
continue
if zhouchang < zhouchang_min:
continue
if zhouchang > zhouchang_max:
continue
if x2 < offset_min:
continue
if x2 > offset_max:
continue
print('面積:', area, '周長:', zhouchang)
count += 1
rect = cv2.minAreaRect(contour) # 检测轮廓最小外接矩形,得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) # 获取最小外接矩形的4个顶点坐标
print(box)
txt11=txt1(q=box,width=w,height=h)
txt22=str(LEEXING)+' '+str(txt11[0])+' '+str(txt11[1])+' '+str(txt11[2])+' '+str(txt11[3])
print(txt22)
cv2.drawContours(draw_rect, [box], 0, (0, 0, 255), 2) # 绘制轮廓最小外接矩形
h, w = image.shape[:2] # 原图像的高和宽
rect_w, rect_h = int(rect[1][0]) + 1, int(rect[1][1]) + 1 # 最小外接矩形的宽和高
if rect_w <= rect_h:
x, y = int(box[1][0]), int(box[1][1]) # 旋转中心
M2 = cv2.getRotationMatrix2D((x, y), rect[2], 1)
rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_h + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_w + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
else:
x, y = int(box[2][0]), int(box[2][1]) # 旋转中心
M2 = cv2.getRotationMatrix2D((x, y), rect[2] + 90, 1)
rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_w + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_h + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
print("rice #{}".format(count))
# cv2.imshow("rotated_canvas", rotated_canvas)
imgs = imgsss.split('\\')
cv2.imwrite("./imgs/{}.jpg".format(imgs[-1]+str(count)), rotated_canvas)
with open("./imgs/{}.txt".format(imgs[-1]+str(count)), 'w') as fp:
fp.write(txt22)
cv2.waitKey(0)
cv2.imwrite("rect.jpg", draw_rect)
def wenjian(path1):
df_list=[]
list212=os.listdir(path1)
for i in list212:
file_path=os.path.join(path1,i)
df_list.append(file_path)
return df_list
def txt1(q,width,height):
x1=q[1][0]
x2=q[3][0]
y1=q[1][1]
y2=q[3][1]
xmin_xishu, xmax_xishu =x1 / width, x2 / width
ymin_xishu, ymax_xishu= y1 / height ,y2 / height
width2=xmax_xishu-xmin_xishu
height2=ymax_xishu-ymin_xishu
x_centr_shu=xmin_xishu+width2/2
y_centr_shu=ymin_xishu+height2/2
return round(x_centr_shu, 6),round(y_centr_shu, 6),round(width2, 6),round(height2, 6)
if __name__ == '__main__':
a=time.time()
path1 = r'E:\0908\1WVE' # 路径
list1=wenjian(path1)
for i in list1:
ceshi1(i)
b=time.time()
c=b-a
print(c)
这个效果可以
import cv2
import numpy as np
import os
import time
GAUSSIAN_BLUR_KERNEL_SIZE=(5,5)
GAUSSIAN_BLUR_SIGMA_X=0
CANNY_THRESHOLD1=120
CANNY_THRESHOLD2=250
LEEXING=12 #要识别的类
def get_gaussian_blur_image(image): #高斯去噪
return cv2.GaussianBlur(image,GAUSSIAN_BLUR_KERNEL_SIZE,GAUSSIAN_BLUR_SIGMA_X)
def get_canny_image(image): #找轮廓
return cv2.Canny(image,CANNY_THRESHOLD1,CANNY_THRESHOLD2)
def get_contours(image): #导出轮廓参数
contours,_=cv2.findContours(image,cv2.RETR_CCOMP,cv2.CHAIN_APPROX_SIMPLE)
return contours
def lp(imgsss): #算轮廓
img1=cv2.imread(imgsss,0)
x1=cv2.Sobel(img1,cv2.CV_16S,1,0,ksize=-1)
y1=cv2.Sobel(img1,cv2.CV_16S,0,1,ksize=-1)
Scale_absX1=cv2.convertScaleAbs(x1)
Scale_absY1=cv2.convertScaleAbs(y1)
result1=cv2.addWeighted(Scale_absX1,0.5,Scale_absY1,0.5,0)
return result1
def ceshi1(imgsss):
image_raw = cv2.imread(imgsss)
h, w, _ = image_raw.shape
mianji_MIN1 = 700000 #最小面积
mianji_MAX1 = 1000000 #3最大面积
zhouchang_min = 3000 #最小周长
zhouchang_max = 5000 最大周长
offset_min = 0.4 * image_raw.shape[1] #最小偏移量
offset_max = 0.99 * image_raw.shape[1] #最大偏移量
img = cv2.imread(imgsss)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #一个算子也可以改改成lp函数里的算子
blurred = cv2.GaussianBlur(gray, (3, 3), 0)
xgrad = cv2.Sobel(blurred, cv2.CV_16SC1, 1, 0)
ygrad = cv2.Sobel(blurred, cv2.CV_16SC1, 0, 1)
edge_output = cv2.Canny(xgrad, ygrad, 50, 150)
rect_Kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3))
image_tophat = cv2.morphologyEx(edge_output, cv2.MORPH_CLOSE, rect_Kernel)
contours = get_contours(image_tophat)
image = cv2.imread(imgsss)
contour = image.copy()
cv2.drawContours(contour, contours, -1, (0, 255, 0), 2)
count = 0 # 个数
margin = 5 # 裁剪边距
draw_rect = image.copy()
for i, contour in enumerate(contours):
area = cv2.contourArea(contour) # 计算包围形状的面积
zhouchang = cv2.arcLength(contour, True)
x2, y2, w2, h2 = cv2.boundingRect(contour)
if area < mianji_MIN1: # 过滤面积小于15的形状
continue
if area > mianji_MAX1: # 过滤面积小于15的形状
continue
if zhouchang < zhouchang_min:
continue
if zhouchang > zhouchang_max:
continue
if x2 < offset_min:
continue
if x2 > offset_max:
continue
print('面積:', area, '周長:', zhouchang)
count += 1
rect = cv2.minAreaRect(contour) # 检测轮廓最小外接矩形,得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv2.boxPoints(rect)) # 获取最小外接矩形的4个顶点坐标
# print(box)
txt11=txt1(q=box,width=w,height=h)
txt22=str(LEEXING)+' '+str(txt11[0])+' '+str(txt11[1])+' '+str(txt11[2])+' '+str(txt11[3])
print(txt22)
cv2.drawContours(draw_rect, [box], 0, (0, 0, 255), 2) # 绘制轮廓最小外接矩形
h, w = image.shape[:2] # 原图像的高和宽
rect_w, rect_h = int(rect[1][0]) + 1, int(rect[1][1]) + 1 # 最小外接矩形的宽和高
if rect_w <= rect_h:
x, y = int(box[1][0]), int(box[1][1]) # 旋转中心
M2 = cv2.getRotationMatrix2D((x, y), rect[2], 1)
rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_h + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_w + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
else:
x, y = int(box[2][0]), int(box[2][1]) # 旋转中心
M2 = cv2.getRotationMatrix2D((x, y), rect[2] + 90, 1)
rotated_image = cv2.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_w + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_h + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
print("rice #{}".format(count))
# cv2.imshow("rotated_canvas", rotated_canvas)
imgs = imgsss.split('\\')
cv2.imwrite("./imgs/{}.jpg".format(imgs[-1]+str(count)), rotated_canvas)
with open("./imgs/{}.txt".format(imgs[-1]+str(count)), 'w') as fp:
fp.write(txt22)
cv2.waitKey(0)
cv2.imwrite("./imgs/{}.png".format(imgs[-1]+str(count)), draw_rect)
# cv2.imwrite("rect.jpg", draw_rect)
def wenjian(path1):
df_list=[] #读取文件夹里的照片
list212=os.listdir(path1)
for i in list212:
file_path=os.path.join(path1,i)
df_list.append(file_path)
return df_list
def txt1(q,width,height): #计算出需要的参数
x1=q[1][0]
x2=q[3][0]
y1=q[1][1]
y2=q[3][1]
xmin_xishu, xmax_xishu =x1 / width, x2 / width
ymin_xishu, ymax_xishu= y1 / height ,y2 / height
width2=xmax_xishu-xmin_xishu
height2=ymax_xishu-ymin_xishu
x_centr_shu=xmin_xishu+width2/2
y_centr_shu=ymin_xishu+height2/2
return round(x_centr_shu, 6),round(y_centr_shu, 6),round(width2, 6),round(height2, 6)
if __name__ == '__main__':
a=time.time()
path1 = r'D:\AOI\18HP' # 路径
list1=wenjian(path1)
for i in list1:
print(i)
ceshi1(i)
b=time.time()
c=b-a
print(c)
单独跑一张图片的
import cv2 as cv
import numpy as np
import time
from matplotlib import pyplot as plt
# kernel = np.ones((3,3),np.uint8) #腐蝕
# dige_erosion = cv.erode(image_canny,kernel,iterations = 1)
#
# kernel = np.ones((3,3),np.uint8) #膨脹
# dige_dilate = cv.dilate(dige_erosion,kernel,iterations = 2)
a=time.time()
imgsss='1.jpg'
CANNY_THRESHOLD1=60
CANNY_THRESHOLD2=150
GAUSSIAN_BLUR_KERNEL_SIZE=(5,5)
GAUSSIAN_BLUR_SIGMA_X=0
image_raw=cv.imread(imgsss)
mianji_MIN1=700000
mianji_MAX1=1000000
zhouchang_min=3000
zhouchang_max=5000
offset_min=0.4*image_raw.shape[1]
offset_max=0.99*image_raw.shape[1]
#拉普算子
def lp(imgsss):
img1=cv.imread(imgsss,0)
x1=cv.Sobel(img1,cv.CV_16S,1,0,ksize=-1)
y1=cv.Sobel(img1,cv.CV_16S,0,1,ksize=-1)
Scale_absX1=cv.convertScaleAbs(x1)
Scale_absY1=cv.convertScaleAbs(y1)
result1=cv.addWeighted(Scale_absX1,0.5,Scale_absY1,0.5,0)
return result1
def zhi():
image = cv.imread(imgsss, cv.IMREAD_GRAYSCALE)
thresh1 = cv.adaptiveThreshold(image, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY, 11, 2)
thresh2 = cv.adaptiveThreshold(image, 255, cv.ADAPTIVE_THRESH_MEAN_C, cv.THRESH_BINARY_INV, 11, 2)
thresh3 = cv.adaptiveThreshold(image, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY, 11, 2)
thresh4 = cv.adaptiveThreshold(image, 255, cv.ADAPTIVE_THRESH_GAUSSIAN_C, cv.THRESH_BINARY_INV, 11, 2)
return thresh1,thresh2,thresh3,thresh4
def erzhi():
# 读取第一张图像
img = cv.imread(imgsss)
# 获取图像尺寸
h, w = img.shape[0:2]
# 自定义空白单通道图像,用于存放灰度图
gray = np.zeros((h, w), dtype=img.dtype)
# 对原图像进行遍历,然后分别对B\G\R按比例灰度化
for i in range(h):
for j in range(w):
gray[i, j] = max(img[i, j, 0], img[i, j, 1], img[i, j, 2]) # 求3通道中最大的值
gray = cv.cvtColor(gray, cv.COLOR_BGR2RGB) # BGR转换为RGB显示格式,方便通过matplotlib进行图像显示
ref_BINARY = cv.threshold(gray, 180, 255, cv.THRESH_BINARY_INV)[1] # 转换成二值图像
return ref_BINARY
'''高斯去噪'''
def get_gaussian_blur_image(image): #高斯去噪
return cv.GaussianBlur(image,GAUSSIAN_BLUR_KERNEL_SIZE,GAUSSIAN_BLUR_SIGMA_X)
def get_canny_image(image):
return cv.Canny(image,CANNY_THRESHOLD1,CANNY_THRESHOLD2)
def get_contours(image):
contours,_=cv.findContours(image,cv.RETR_CCOMP,cv.CHAIN_APPROX_SIMPLE)
return contours
img = cv.imread(imgsss)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
blurred = cv.GaussianBlur(gray, (3, 3), 0)
xgrad = cv.Sobel(blurred, cv.CV_16SC1, 1, 0)
ygrad = cv.Sobel(blurred, cv.CV_16SC1, 0, 1)
edge_output = cv.Canny(xgrad, ygrad, 50, 150)
rect_Kernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 3))
image_tophat = cv.morphologyEx(edge_output, cv.MORPH_CLOSE, rect_Kernel)
# #高斯去噪
# result2=get_gaussian_blur_image(result1)
# #均值
# result3 = cv.blur(result2,(3,3))
#提取輪廓
# image_canny=get_canny_image(s1)
#膨脹
# kernel = np.ones((3,3),np.uint8)
# dige_dilate1 = cv.dilate(image_canny,kernel,iterations = 1)
#中值
# median = cv.medianBlur(image_canny,5)
contours=get_contours(image_tophat)
image = cv.imread(imgsss)
contour = image.copy()
cv.drawContours(contour, contours, -1, (0, 255, 0), 2)
count = 0 # 个数
margin = 5 # 裁剪边距
draw_rect = image.copy()
for i, contour in enumerate(contours):
area = cv.contourArea(contour) # 计算包围形状的面积
zhouchang = cv.arcLength(contour, True)
x2,y2,w2,h2=cv.boundingRect(contour)
if area < mianji_MIN1: # 过滤面积小于15的形状
continue
if area >mianji_MAX1: # 过滤面积小于15的形状
continue
if zhouchang<zhouchang_min:
continue
if zhouchang>zhouchang_max:
continue
if x2 < offset_min:
continue
if x2 > offset_max:
continue
print('面積:',area ,'周長:',zhouchang)
count += 1
rect = cv.minAreaRect(contour) # 检测轮廓最小外接矩形,得到最小外接矩形的(中心(x,y), (宽,高), 旋转角度)
box = np.int0(cv.boxPoints(rect)) # 获取最小外接矩形的4个顶点坐标
# print(box)
cv.drawContours(draw_rect, [box], 0, (0, 0,255), 2) # 绘制轮廓最小外接矩形
h, w = image.shape[:2] # 原图像的高和宽
rect_w, rect_h = int(rect[1][0]) + 1, int(rect[1][1]) + 1 # 最小外接矩形的宽和高
if rect_w <= rect_h:
x, y = int(box[1][0]), int(box[1][1]) # 旋转中心
M2 = cv.getRotationMatrix2D((x, y), rect[2], 1)
rotated_image = cv.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_h + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_w + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
else:
x, y = int(box[2][0]), int(box[2][1]) # 旋转中心
M2 = cv.getRotationMatrix2D((x, y), rect[2] + 90, 1)
rotated_image = cv.warpAffine(image, M2, (w * 2, h * 2))
y1, y2 = y - margin if y - margin > 0 else 0, y + rect_w + margin + 1
x1, x2 = x - margin if x - margin > 0 else 0, x + rect_h + margin + 1
rotated_canvas = rotated_image[y1: y2, x1: x2]
print("rice #{}".format(count))
# cv2.imshow("rotated_canvas", rotated_canvas)
cv.imwrite("./imgs/{}.jpg".format(count), rotated_canvas)
cv.waitKey(0)
cv.imwrite("rect.jpg", draw_rect)
b=time.time()
c=b-a
print(c)
plt.figure()
plt.imshow(image_tophat)
plt.title("space")
plt.show()