我想在python中使用OpenCV识别给定图像中的托盘是否为空。
以下是我尝试过的
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
thresh = cv2.erode(thresh, kernel, iterations=4)
thresh = cv2.dilate(thresh, kernel, iterations=4)
cnts, hier = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# Find the biggest contour
max_area = -1
max_c = 0
for i in range(len(cnts)):
contour = cnts[i]
area = cv2.contourArea(contour)
if (area > max_area):
max_area = area
max_c = i
contour = cnts[max_c]
areas = [cv2.contourArea(c) for c in cnts]
max_index = np.argmax(areas)
cnt=cnts[max_index]
x,y,w,h = cv2.boundingRect(cnt)
crop_img = img[y:y+h, x:x+w]
#Create empty mask and flood fill
mask = np.zeros(edges.shape)
#Create 3-channel alpha mask
mask_stack = np.dstack([mask]*3)
它适用于中型和大型物体,但当我放硬币等小型物体时,这种方法不起作用,因为托盘也有一些划痕和灰尘。这是我在python中使用OpenCV的第一个项目
请帮助找到满足此要求的解决方案。
我建议您:
鉴于上面的图片,这里有一个蛮力解决方案:
#!/usr/bin/python3
# -*- coding: utf-8 -*-
import cv2
import numpy as np
# Ref: https://stackoverflow.com/questions/37177811
def crop_minAreaRect(img, rect):
box = cv2.boxPoints(rect)
box = np.int0(box)
W = rect[1][0]
H = rect[1][1]
Xs = [i[0] for i in box]
Ys = [i[1] for i in box]
x1 = min(Xs)
x2 = max(Xs)
y1 = min(Ys)
y2 = max(Ys)
angle = rect[2]
rotated = False
if angle < -45:
angle += 90
rotated = True
# Center of rectangle in source image
center = ((x1+x2)/2,(y1+y2)/2)
# Size of the upright rectangle bounding the rotated rectangle
size = (x2-x1, y2-y1)
M = cv2.getRotationMatrix2D((size[0]/2, size[1]/2), angle, 1.0)
# Cropped upright rectangle
cropped = cv2.getRectSubPix(img, size, center)
cropped = cv2.warpAffine(cropped, M, size)
croppedW = W if not rotated else H
croppedH = H if not rotated else W
# Final cropped & rotated rectangle
croppedRotated = cv2.getRectSubPix(cropped, (int(croppedW),int(croppedH)), (size[0]/2, size[1]/2))
return croppedRotated
def ROI(img):
hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower_hsv = np.array([0, 0, 135]) # 0, 0, 135
higher_hsv = np.array([180, 20, 240]) # 180, 20, 240
mask = cv2.inRange(hsv, lower_hsv, higher_hsv)
seg = cv2.bitwise_and(img, img, mask=mask)
seg_gray = cv2.cvtColor(seg, cv2.COLOR_BGR2GRAY)
k1 = 51
seg_gauss = cv2.GaussianBlur(seg_gray, (k1, k1), 0)
seg_th = cv2.threshold(seg_gauss, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)[1]
contours, hierarchy = cv2.findContours(image=seg_th, mode=cv2.RETR_EXTERNAL, method=cv2.CHAIN_APPROX_NONE)
for i, cnt in enumerate(contours):
if cv2.contourArea(cnt)>1000000:
x,y,w,h = cv2.boundingRect(cnt)
rect = cv2.minAreaRect(cnt)
roi = crop_minAreaRect(img, rect)
return roi
def ImProc(roi):
gray = cv2.cvtColor(roi, cv2.COLOR_BGR2GRAY)
k_smooth = 5
gauss = cv2.GaussianBlur(gray, (k_smooth, k_smooth), 0)
# # Canny
edges = cv2.Canny(gauss,0,255)
k = 31 #300
kernel = np.ones((k,k),np.uint8)
mph = cv2.morphologyEx(edges, cv2.MORPH_CLOSE, kernel)
res = cv2.medianBlur(mph, 21)
return res
我将这种方法应用于给定的图像:
empty = cv2.imread("empty.jpg")
full = cv2.imread("full.jpg")
roi_empty = ROI(empty)
roi_full = ROI(full)
res_empty = ImProc(roi_empty)
res_full = ImProc(roi_full)
cv2.namedWindow("res_full", cv2.WINDOW_NORMAL)
cv2.imshow("res_full", res_full)
cv2.waitKey(0)
对于满托盘(旋转),我得到了以下结果:
请注意,此解决方案受不同参数的影响,为了更好地控制它们并获得稳定的结果,我建议您考虑上面的建议。
问题内容: 我正在使用postgreSQL。我有一列: 但是,当我想插入带有空字符串的行时,如下所示: 它不会给我错误并接受。如何检查插入值应为?(既不为空也不为空) PS: 我的专栏定义为: 问题答案: 向列定义添加约束。例如类似: 有关更多信息,请参见http://www.postgresql.org/docs/current/static/ddl- constraints.html
我想运行一个复杂的HQL查询。我的一个参数是< code >集合 类似: spring甚至不能启动< code >???未映射 从表t中选择t,其中size((:codes)) = 0或t.code IN (:codes) 和许多其他人 是否有一种通用方法可以进行此检查并使此查询在不完全构建查询的情况下工作?
问题内容: 考虑以下代码块: 当我在构造函数中初始化两个变量(和)时,其他两个变量(和)是否需要内存中的空间来存储null值? Q1。如果它们确实需要空间,那么值将占用多少内存?(例如,占用4个字节)。 Q2。字符串在内存中占用多少空间?字符串需要多少存储空间?它取决于字符串的长度吗? 问题答案: 在Java中,它只是引用(基本上是受限制的指针)可以具有的值。这意味着引用没有任何意义。在这种情况下
随着新的工具栏小部件的引入和AppCompat(android.support.v7.widget.Toolbar)版本的推出,是否还需要调用setSupportActionbar(工具栏)?或者调用setSupportActionbar有什么好处吗;现在我们可以设置标题、子标题、导航图标、导航图标单击侦听器(getSupportActionBar()。直接在工具栏上设置DisplayHomeAs
主要的问题是如何检测雄辩的收集结果是否为空,laravel建议如何识别这一点? 关于这件事我有两个不同的问题,也许他们之间有没有关系, 第一个: 我怎么能得到
以下是我的加速器代码: