首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何从侧视图计算堆叠的纸张

如何从侧视图计算堆叠的纸张
EN

Stack Overflow用户
提问于 2021-10-06 12:17:16
回答 1查看 164关注 0票数 1

我想要计算一叠纸的数量,就像你在堆叠的侧视图中看到的那样。

我已经实现了一些解决方案,但它不起作用。我仍然得到输出的行数为0。有没有人会支持我来解决这个问题?

仅供参考:输出图像在经过精明的边缘检测后附加。提前感谢!

代码语言:javascript
复制
import numpy as np
import os
import cv2
import matplotlib.pyplot as plt
import scipy
from skimage import io


def Canny_detector(img, weak_th=None, strong_th=None):
    # conversion of image to grayscale
    img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # Noise reduction step
    img = cv2.GaussianBlur(img, (5, 5), 1.4)

    # Calculating the gradients
    gx = cv2.Sobel(np.float32(img), cv2.CV_64F, 1, 0, 3)
    gy = cv2.Sobel(np.float32(img), cv2.CV_64F, 0, 1, 3)

    # Conversion of Cartesian coordinates to polar
    mag, ang = cv2.cartToPolar(gx, gy, angleInDegrees=True)

    # setting the minimum and maximum thresholds
    # for double thresholding
    mag_max = np.max(mag)
    if not weak_th: weak_th = mag_max * 0.1
    if not strong_th: strong_th = mag_max * 0.5

    # getting the dimensions of the input image
    height, width = img.shape

    # Looping through every pixel of the grayscale
    # image
    for i_x in range(width):
        for i_y in range(height):

            grad_ang = ang[i_y, i_x]
            grad_ang = abs(grad_ang - 180) if abs(grad_ang) > 180 else abs(grad_ang)
            #print("yyy")
            # selecting the neighbours of the target pixel
            # according to the gradient direction
            # In the x axis direction
            if grad_ang <= 22.5:
                neighb_1_x, neighb_1_y = i_x - 1, i_y
                neighb_2_x, neighb_2_y = i_x + 1, i_y

            # top right (diagonal-1) direction
            elif grad_ang > 22.5 and grad_ang <= (22.5 + 45):
                neighb_1_x, neighb_1_y = i_x - 1, i_y - 1
                neighb_2_x, neighb_2_y = i_x + 1, i_y + 1

            # In y-axis direction
            elif grad_ang > (22.5 + 45) and grad_ang <= (22.5 + 90):
                neighb_1_x, neighb_1_y = i_x, i_y - 1
                neighb_2_x, neighb_2_y = i_x, i_y + 1

            # top left (diagonal-2) direction
            elif grad_ang > (22.5 + 90) and grad_ang <= (22.5 + 135):
                neighb_1_x, neighb_1_y = i_x - 1, i_y + 1
                neighb_2_x, neighb_2_y = i_x + 1, i_y - 1

            # Now it restarts the cycle
            elif grad_ang > (22.5 + 135) and grad_ang <= (22.5 + 180):
                neighb_1_x, neighb_1_y = i_x - 1, i_y
                neighb_2_x, neighb_2_y = i_x + 1, i_y

            # Non-maximum suppression step
            if width > neighb_1_x >= 0 and height > neighb_1_y >= 0:
                if mag[i_y, i_x] < mag[neighb_1_y, neighb_1_x]:
                    mag[i_y, i_x] = 0
                    continue

            if width > neighb_2_x >= 0 and height > neighb_2_y >= 0:
                if mag[i_y, i_x] < mag[neighb_2_y, neighb_2_x]:
                    mag[i_y, i_x] = 0

    weak_ids = np.zeros_like(img)
    strong_ids = np.zeros_like(img)
    ids = np.zeros_like(img)

    # double thresholding step
    for i_x in range(width):
        for i_y in range(height):
            grad_mag = mag[i_y, i_x]

            if grad_mag < weak_th:
                mag[i_y, i_x] = 0
            elif strong_th > grad_mag >= weak_th:
                ids[i_y, i_x] = 1
            else:
                ids[i_y, i_x] = 2

    # finally returning the magnitude of gradients of edges
    return mag

frame = cv2.imread('/Users/Projects/Image/IMG1.jpg')

print("Hi there")
# calling the designed function for finding edges


canny_img = Canny_detector(frame)

# Displaying the input and output image
plt.figure()

plot1 = plt.figure(1)
plt.imshow(frame)

plot2 = plt.figure(2)
plt.imshow(canny_img)

print("Hallo Hallo")
plt.show()

#J. Canny. 1986. (Canny)
#Smooth Image with Gaussian filter
#Compute Derivative of filtered image
#Find Magnitude and Orientation of gradient
#Apply Non-max suppression
#Apply Thresholding (Hysteresis)

rho = 1  # distance resolution in pixels of the Hough grid
theta = np.pi / 180  # angular resolution in radians of the Hough grid
threshold = 15  # minimum number of votes (intersections in Hough grid cell)
min_line_length = 50  # minimum number of pixels making up a line
max_line_gap = 20  # maximum gap in pixels between connectable line segments
line_image = np.copy(frame) * 0  # creating a blank to draw lines on



print(rho)
print("Hey there")
# After you apply Hough on edge detected image. Let's define the function which turns 
these edges into lines

canny_img = canny_img.astype(np.uint8)
lines = cv2.HoughLinesP(canny_img, rho, theta, threshold, np.array([]),
                min_line_length, max_line_gap)
print(lines)

# calculate the distances between points (x1,y1), (x2,y2) :
distance = []
for line in lines:
    distance.append(np.linalg.norm(line[:,:2] - line[:,2:]))
    print(distance)

print('max distance:', max(distance), '\nmin distance:', min(distance))

# Adjusting the best distance
bestDistance=1110

numberOfLines=[]
count=0
for x in distance:
    if x>bestDistance:
        numberOfLines.append(x)
        count=count+1

print('Number of lines:', count)
EN

回答 1

Stack Overflow用户

发布于 2021-10-06 23:26:20

在这里,我使用精明的边缘检测和概率Hough变换来检测您的线条。

First imports和边缘检测

代码语言:javascript
复制
import cv2
import numpy as np
from matplotlib import pyplot as plt
import sympy as sp
sp.var('b,x')

img0 = cv2.imread('eRVR4.jpg',)
gray = cv2.cvtColor(img0, cv2.COLOR_BGR2GRAY)
for _ in range(5):
    gray = cv2.GaussianBlur(gray,(3,3),0)

gray = cv2.Canny(gray, 100, 200)
plt.imshow(gray,cmap='gray')

接下来,我使用概率霍夫变换cv2.HoughLinesP并绘制结果。

代码语言:javascript
复制
img = np.zeros(gray.shape)

lines = cv2.HoughLinesP(gray.copy(),1, np.pi/180, 100, minLineLength=150, maxLineGap=25)
mid_xs = []

for x1, y1, x2, y2 in lines.reshape(-1,4):
    slope = (y2-y1)/(x2-x1)
    intercept = sp.solve(sp.Eq(slope*x1+b,y1))[0]
    mid_x = float(sp.solve(slope*x+intercept-200)[0])
    mid_xs.append(mid_x)
    cv2.line(img, (x1, y1), (x2, y2), (255, 255, 255), 2)
    
mid_xs = np.sort(np.array(mid_xs))
plt.imshow(img, cmap='gray')

这看起来几乎完美,但有两对线的距离几乎为零,一对线的距离很小。我在这里的想法是,我想要计算距离并删除异常值。然后,为了得到一个好的结果图,我看看在to small gap之前或之后删除这条线是否最有帮助,然后这样做。

代码语言:javascript
复制
distances = mid_xs[1:]-mid_xs[:-1]
median = np.median(distances)

@np.vectorize
def decide_what_to_remove(i):
    arr = mid_xs[i-1:i+3]
    mse1 = calc_mean_sq_error(np.delete(arr,1))
    mse2 = calc_mean_sq_error(np.delete(arr,2))
    return i if mse1 < mse2 else i+1
    
def calc_mean_sq_error(arr):
    distances = arr[1:]-arr[:-1]
    return np.mean((distances-median)**2)


problematic_distances = np.where(np.abs(distances-median) > 15)[0]
to_delete = decide_what_to_remove(problematic_distances)
mid_xs = np.delete(mid_xs, to_delete, axis=0)

最后,我可以标记原始图片中的线条,以检查是否达到了我想要的效果。

代码语言:javascript
复制
img = cv2.imread('eRVR4.jpg')

for x in mid_xs:
    cv2.circle(img,(int(x),200),5,(0, 255, 0),2)

plt.imshow(img, cmap='gray')

哦,len(mid_xs)告诉我,我已经标记了23行。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69465576

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档