在这里之间写代码:
import numpy as np
import torch
import torch.nn as nn
import cv2
#1.silu激活函数
class SiLU(nn.Module):
@staticmethod
def forward(x):
return x*torch.sigmoid(x)
#2.获得轨道的类
def railway_classes3(img,x1,x2,y1,y2):
img2 = img[x1:x2, y1:y2, :]
return img2
class Conv(nn.Module):
def __init__(self):
super(Conv, self).__init__()
#标准化加激活函数
self.bn = nn.BatchNorm2d(3)#标准化
self.act = SiLU()
def forward(self,x):
#x=self.conv(x)
x=self.bn(x)
x= self.act(x)
return x
if __name__ == "__main__":
#输入图片路径
image=cv2.imread(r"imgs/000002.jpg")
img2=railway_classes3(image, x1=640, x2=740, y1=825, y2=1025)
cv2.imshow("ss",img2)
cv2.waitKey(0)
cv2.imwrite("imgs/00.jpg",img2)
images = img2.reshape(1, 3, img2.shape[0], img2.shape[1])
data = torch.tensor(images)
datas = torch.tensor(images, dtype=torch.float32)
sp=Conv()
output=sp(datas)
ar=output.detach().numpy()
result=ar.reshape(img2.shape[0], img2.shape[1],3)
print(result)
#图片处理
for i in range(result.shape[0]):
for j in range(1,result.shape[1]-2):
ss1 = result[i, j - 1:j + 2,:].mean()
m = result[i][j].mean() - ss1
if m >= ss1:
print(ss1)
img2[i][j] = 255
else:
img2[i][j] = 0
img2[:, -3:] = 0
img2[:, :3] = 0
cv2.imshow("ss", img2)
cv2.waitKey(0)
处理效果如下:
第一张光线比较强的图片:
原图 二值化图
第二张光线比较暗的图
原图 二值化图
以上图片处理的方式用了BatchNorm处理和Xsilu处理,最后感觉这种效果还可以,尤其是在强光下的效果。
2.用普通的计算方法代码如下:
import numpy as np
import cv2
import time
import os
colors = [ (0, 0, 0), (128, 0, 0), (0, 128, 0), (128, 128, 0), (0, 0, 128), (128, 0, 128), (0, 128, 128),
(128, 128, 128), (64, 0, 0), (192, 0, 0), (64, 128, 0), (192, 128, 0), (64, 0, 128), (192, 0, 128),
(64, 128, 128), (192, 128, 128), (0, 64, 0), (128, 64, 0), (0, 192, 0), (128, 192, 0), (0, 64, 128),
(128, 64, 12)]
def cluster(points, radius=100):
"""
points: pointcloud
radius: max cluster range
"""
print("................", len(points))
items = []
while len(points)>1:
item = np.array([points[0]])
base = points[0]
points = np.delete(points, 0, 0)
distance = (points[:,0]-base[0])**2+(points[:,1]-base[1])**2#获得距离
infected_points = np.where(distance <= radius**2)#与base距离小于radius**2的点的坐标
item = np.append(item, points[infected_points], axis=0)
border_points = points[infected_points]
points = np.delete(points, infected_points, 0)
while len(border_points) > 0:
border_base = border_points[0]
border_points = np.delete(border_points, 0, 0)
border_distance = (points[:,0]-border_base[0])**2+(points[:,1]-border_base[1])**2
border_infected_points = np.where(border_distance <= radius**2)
#print("/",border_infected_points)
item = np.append(item, points[border_infected_points], axis=0)
if len(border_infected_points)>0:
for k in border_infected_points:
if points[k] not in border_points:
border_points=np.append(border_points,points[k], axis=0)
#border_points = points[border_infected_points]
points = np.delete(points, border_infected_points, 0)
items.append(item)
return items
#2.获得轨道的类
def railway_classes(img,x1,x2,y1,y2):
img2 = img[x1:x2, y1:y2, :] # [540:741, 810:1080],截取轨道画线的区域,对该区域识别轨道
print("img2:", img2.shape)
dst = np.zeros((img2.shape[0], img2.shape[1]), np.uint8)
for i in range(img2.shape[0]):
for j in range(2, img2.shape[1] - 2):
z = img2[i, j - 2:j + 2]
# print(z)
a_z = np.average(z, axis=0) # 按列求均值
# print(a_z)
m = abs(img2[i][j] - a_z).max()
# print(m)
if m > 12:
dst[i][j] = 255
else:
dst[i][j] = 0
cv2.imshow("ss", dst)
cv2.waitKey(0)
img2=dst
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\170.jpg", img2)
# 3.腐蚀膨胀消除轨道线外的点
kernel = np.uint8(np.ones((5, 1)))
# 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方
dilated = cv2.dilate(img2, kernel)
kernel = np.ones((2, 3), np.uint8)
dilated = cv2.erode(dilated, kernel)
#
ss=np.argwhere(dilated >0)#dilated
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\120.jpg",dilated)
cv2.imshow("ss", dilated)
cv2.waitKey(0)
#聚类算法
t1=time.time()
items = cluster(ss, radius=3)
i=0
out=[]#获得大于300个坐标的类
for item in items:
if len(item)>180:
out.append(item)
for k in item:
img[k[0]+x1][k[1]+y1]=colors[i]
i+=1
t2=time.time()
print("dbscan消耗时间:",t2-t1)
cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\0.jpg", img)
return out
#2.获得轨道的类
def railway_classes2(img,x1,x2,y1,y2):
img2 = img[x1:x2, y1:y2, :] # [540:741, 810:1080],截取轨道画线的区域,对该区域识别轨道
print("img2:", img2.shape)
dst = np.zeros((img2.shape[0], img2.shape[1]), np.uint8)
for i in range(img2.shape[0]):
for j in range(2, img2.shape[1] - 2):
z = img2[i, j - 2:j + 2]
# print(z)
a_z = np.average(z, axis=0) # 按列求均值
# print(a_z)
m = abs(img2[i][j] - a_z).max()
# print(m)
if m > 12:
dst[i][j] = 255
else:
dst[i][j] = 0
cv2.imshow("ss", dst)
cv2.waitKey(0)
img2=dst
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\170.jpg", img2)
# 3.腐蚀膨胀消除轨道线外的点
kernel = np.uint8(np.ones((5, 1)))
# 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方
dilated = cv2.dilate(img2, kernel)
kernel = np.ones((2, 3), np.uint8)
dilated = cv2.erode(dilated, kernel)
#
ss=np.argwhere(dilated >0)#dilated
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\120.jpg",dilated)
cv2.imshow("ss", dilated)
cv2.waitKey(0)
#聚类算法
t1=time.time()
items = cluster(ss, radius=3)
i=0
out=[]#获得大于300个坐标的类
for item in items:
if len(item)>80:
out.append(item)
for k in item:
img[k[0]+x1][k[1]+y1]=colors[i]
i+=1
t2=time.time()
print("dbscan消耗时间:",t2-t1)
cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\0.jpg", img)
return out
#2.获得轨道的类
def railway_classes3(img,x1,x2,y1,y2):
img2 = img[x1:x2, y1:y2, :] # [540:741, 810:1080],截取轨道画线的区域,对该区域识别轨道
print("img2:", img2.shape)
dst = np.zeros((img2.shape[0], img2.shape[1]), np.uint8)
for i in range(img2.shape[0]):
for j in range(2, img2.shape[1] - 2):
z = img2[i, j - 2:j + 2]
# print(z)
a_z = np.average(z, axis=0) # 按列求均值
# print(a_z)
m = abs(img2[i][j] - a_z).max()
# print(m)
if m > 11:
dst[i][j] = 255
else:
dst[i][j] = 0
cv2.imshow("ss", dst)
cv2.waitKey(0)
img2=dst
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\170.jpg", img2)
# # 3.腐蚀膨胀消除轨道线外的点
kernel = np.uint8(np.ones((4, 2)))
# 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方
dilated = cv2.dilate(img2, kernel)
kernel = np.ones((3, 3), np.uint8)
dilated = cv2.erode(dilated , kernel)
# #
# kernel = np.uint8(np.ones((5, 2)))
# # 膨胀图像.....为了使得轨道线更粗,且补足轨道线缺失的地方
# dilated = cv2.dilate(dilated, kernel)
ss=np.argwhere(dilated >0)#dilated
# cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\120.jpg",dilated)
cv2.imshow("ss", dilated)
cv2.waitKey(0)
#聚类算法
t1=time.time()
items = cluster(ss, radius=3)
i=0
out=[]#获得大于300个坐标的类
for item in items:
if len(item)>80:
out.append(item)
for k in item:
img[k[0]+x1][k[1]+y1]=colors[i]
i+=1
t2=time.time()
print("dbscan消耗时间:",t2-t1)
cv2.imwrite("D:\AI\project\eye_hand_biaoding\\railways\dbscan\img\\0.jpg", img)
return out
#以15个左右的像素点,将类每个类分为很多个小类画直线
def fenlei(classes,num):
class_mean=[]
for item in classes:
item_classes=[]
#获取初始点的值
hh=item[:5]
y=hh[0][0]
x=int(hh[:,-1:].mean())
item_classes.append((x, y))
item =item[item[:,0].argsort()]
#对数据分成很多个段,再
while len(item) > num+15:
items=item[:num]
s1=items
y10=int(s1[:, :1].mean())
x10=int(s1[:,-1:].mean())
item_classes.append((x10,y10))
item=item[120:]
if len(item)>5:
s1 = item
y10 = int(s1[:, :1].mean())
x10 = int(s1[:, -1:].mean())
item_classes.append((x10, y10))
class_mean.append(item_classes)
all_k=[]
for item in class_mean:
k_b=[]
for i in range(len(item)-1):
x10,y10=item[i][0],item[i][1]
x20, y20 = item[i+1][0], item[i+1][1]
k1=(y10-y20)/(x10-x20+0.00001)
b1=y10-k1*x10
k_b.append((k1, b1, [y10,y20]))
all_k.append(k_b)
print(all_k)
return all_k
#画线
def draw_line(img,all_k,x1,x2,y1,y2):
print("......................画直线.............................")
for k_b in all_k:
ss=np.array(k_b)
ks=np.array(ss[:,:1]/len(ss)).sum()*0.5
#print(ks)
for i in range(len(k_b)):
k, b, (y10, y20) = k_b[i]
x10 = int((y10 - b) / (k+0.000001))
x20 = int((y20 - b) / (k+0.000001))
cv2.line(img, (x10 + y1, y10 + x1), (x20 + y1, y20 + x1), (0, 0, 255), 2)
cv2.imshow("line_detect_possible_demo", img)
cv2.waitKey(0)
if __name__ == '__main__':
start=time.time()
img_paths = r"imgs\000004.jpg"
save_paths = r"imgs\20.jpg"
img = cv2.imread(img_paths)
img2=img.copy()
all_class = {}
all_class["1"] = []
all_class["2"] = []
# 第1次*************************************************************************************
#获得轨道的类
classes=railway_classes(img, x1=680, x2=740, y1=825, y2=1045)#
# 求第一段的类
all_class["1"].append(classes[0])
all_class["2"].append(classes[1])
start1 = classes[0][:20, 1:].mean() + 825
start2 = classes[1][:20, 1:].mean() + 825
print(start1, start2)
#=============================================================================================================
# classes2 = railway_classes2(img, x1=640, x2=680, y1=845, y2=995) #
# print("......................................................")
# # 求第一段的类
# for item in classes2:
# # print("start===>",item[:20,1:].mean()+845)
# # print("end===>",item[-20:,1:].mean()+845)
# if abs((item[-20:, 1:].mean() + 845) - start1) < 10:
# np.vstack((all_class["1"][0], item))
# start1 = item[:20, 1:].mean() + 845
# elif abs((item[-20:, 1:].mean() + 845) - start2) < 10:
# np.vstack((all_class["2"][0], item))
# start2 = item[:20, 1:].mean() + 845
# print(start1, start2)
#
# # =============================================================================================================
# classes3 = railway_classes3(img, x1=610, x2=640, y1=855, y2=965) #
# print("......................................................")
# for item in classes3:
# # print("start===>",item[:,1:].mean()+855)
# # print("end===>", item[-20:, 1:].mean() + 855)
# if abs((item[-20:, 1:].mean() + 855) - start1) < 10:
# np.vstack((all_class["1"][0], item))
# start1 = item[:20, 1:].mean() + 855
# elif abs((item[-20:, 1:].mean() + 855) - start2) < 10:
# np.vstack((all_class["2"][0], item))
# start2 = item[:20, 1:].mean() + 855
# print(start1, start2)
ss=[]
ss.append(all_class["1"][0])
ss.append(all_class["2"][0])
print(ss[0])
# 以15个左右的像素点,将类每个类分为很多个小类画直线
num=100
all_k=fenlei(ss,num)#classes
#
# # 画线
draw_line(img, all_k, x1=680, x2=740, y1=825, y2=1035)#