Extração de centro de franja a laser - método de centro em tons de cinza python
método do centro cinza
O método do centroide de escala de cinza é processar linha por linha de acordo com as características de distribuição de escala de cinza na seção transversal de cada linha de franjas claras. A área é calculada e extraída linha por linha, e este ponto é usado como A posição do ponto central da faixa de luz que representa a seção e, finalmente, todos os pontos centrais são ajustados para formar a linha central da faixa de luz. As etapas específicas da operação são primeiro filtrar a imagem para remover o ruído e, em seguida, usar o limite para segmentar e reter a parte maior que o limite. O intervalo (m, n) é determinado pelo limite T. A fórmula para calcular o ponto central da faixa de luz pelo método bariccêntrico em escala de cinza é mostrada na fórmula (1-7). A coordenada baricêntrica em escala de cinza da coluna v da faixa de luz é o pixel na coordenada (u , v) na imagem incluindo a linha U e a coluna V. O valor da escala de cinza é I(u,v), onde u=1,2,3,…,U;v=1,2,3…,V.
O método do centroide da escala de cinza reduz o erro causado pela distribuição desigual de cinza das faixas de luz e melhora a precisão da extração da linha central da faixa de luz. linha central da faixa de luz. A velocidade de cálculo é rápida e o desempenho em tempo real é bom. . No entanto, como o número total de pontos de pixel envolvidos no cálculo na seção de faixa de luz de cada linha é diferente, a interferência de ruído também afetará a precisão do cálculo, de modo que as coordenadas de posição do ponto central terão um erro de deslocamento ao longo da coordenada da linha direção.
código python
import cv2
import numpy as np
def getLines(gray):
minLineLength = 15
maxLineGap = 5
lines = cv2.HoughLinesP(gray, 1.0, np.pi/180, 10, minLineLength=minLineLength, maxLineGap=maxLineGap)
return lines
def drawLine(lines,img):
for line in lines:
line = line[0]
cv2.line(img, (line[0], line[1]), (line[2], line[3]), 255)
def Gravity(img):
row,col,chanel = img.shape
lineimage = np.zeros((row,col),dtype=np.uint8)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
points= []
newimage = np.zeros((row,col),np.uint8)
for i in range(col):
Pmax = np.max(gray[:,i])
Prow = np.argmax(gray[:,i])
#print(Prow)
points.append([Prow,i])
for p in points:
#print(p)
newimage[p[0],p[1]] = 255
img[p[0],p[1],:] = [0,255,0]
cv2.namedWindow("origin",0)
cv2.namedWindow("centerLine",0)
lines = getLines(newimage)
drawLine(lines,lineimage)
cv2.imshow("origin",img)
cv2.imshow("lineimage",lineimage)
cv2.imshow("centerLine",newimage)
def GravityPlus(img, thresh):
row, col, chanel = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
points = np.zeros((col,2))
newimage = np.zeros((row, col), np.uint8)
for i in range(col):
Pmax = np.max(gray[:, i])
#Pmin = np.min(gray[:, i])
if Pmax < thresh:
continue
pos = np.argwhere(gray[:,i]>=(Pmax-5))
#print("pos",pos)
length = len(pos)
sum_top,sum_down = 0.0, 0.0
if pos[-1]-pos[0] == length - 1:
#print("good cols",i)
for p in pos:
sum_top += p*gray[p,i]
sum_down += gray[p,i]
Prow = sum_top / sum_down
points[i]=[Prow[0],i]
for p in points:
#print(p)
pr,pc = map(int,p)
newimage[pr,pc] = 255
img[pr,pc,:] = [0,0,225]
# cv2.namedWindow("Plus_origin",0)
# cv2.namedWindow("Plus_centerLine",0)
# cv2.imshow("Plus_origin",img)
# cv2.imshow("Plus_centerLine",newimage)
return img, newimage
def GravityPlusK(img,thresh,k):
row, col, chanel = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
points = np.zeros((col,2))
newimage = np.zeros((row, col), np.uint8)
for i in range(col):
posMax = np.argmax(gray[:, i])
Pmax = gray[posMax, i]
#Pmin = np.min(gray[:, i])
if Pmax<thresh:
continue
sumPix = 0
sumVal = 0
for index in range(-k,k):
sumPix+=gray[posMax+index,i]*(posMax+index)
sumVal+=gray[posMax+index,i]
valCenter =sumPix/sumVal
points[i]=[valCenter,i]
print(points)
for p in points:
#print(p)
pr,pc = map(int,p)
newimage[pr,pc] = 255
img[pr,pc,:] = [0,0,255]
cv2.namedWindow("Plus_origin",0)
cv2.namedWindow("Plus_centerLine",0)
cv2.imshow("Plus_origin",img)
cv2.imshow("Plus_centerLine",newimage)
return points
import time
start_time = time.time()
img = cv2.imread("./crop.png")
GravityPlus(img,100)
cv2.imshow("image", img)
cv2.waitKey(0)
print("One image need time: ", time.time() - start_time)
# if __name__ == "__main__":
# import time
# import os
# import tqdm
# image_path = "./image/"
# save_path = "./paper/ggm/"
# if not os.path.isdir(save_path): os.makedirs(save_path)
#
# sum_time = 0
# for img in tqdm.tqdm(os.listdir(image_path)):
# image = cv2.imread(os.path.join(image_path, img))
# start_time = time.time()
# _, image_c = GravityPlus(image, 50)
# end_time = time.time()
# sum_time += end_time - start_time
# cv2.imwrite(os.path.join(save_path, img), image_c)
# average_time = sum_time / len(os.listdir(image_path))
# print("Average one image time: ", average_time)
import cv2
import numpy as np
import time
def GravityCen(img):
row, col, chanel = img.shape
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
points = []
newimage = np.zeros((row, col), np.uint8)
for i in range(col):
pos = np.argmax(gray[:, i])
Pmax = gray[pos, i]
Pmin = np.min(gray[:, i])
if Pmax==Pmin:
continue
length = 2
sum =0.0
down = 0.0
for j in range(-2,3):
colp = pos+j
print(colp)
sum += colp*gray[colp,i]
down +=gray[colp,i]
Prow = sum/down
points.append([Prow,i])
for p in points:
#print(p)
pr,pc = map(int,p)
newimage[pr,pc] = 255
img[pr,pc,:] = [0,255,0]
cv2.namedWindow("Plus_origin",0)
cv2.namedWindow("Plus_centerLine",0)
cv2.imshow("Plus_origin",img)
cv2.imshow("Plus_centerLine",newimage)
return points
start_time = time.time()
img = cv2.imread("./3.png")
#gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#np.savetxt("laser-v02.txt",gray,fmt="%.3d")
#rows,cols = gray.shape
blur = cv2.blur(img,(5,5))
points = GravityCen(blur)
#cv2.imshow("gray",gray)
cv2.imshow("blur",blur)
cv2.waitKey(0)
print("One image need time: ", time.time() - start_time)