- android - 多次调用 OnPrimaryClipChangedListener
- android - 无法更新 RecyclerView 中的 TextView 字段
- android.database.CursorIndexOutOfBoundsException : Index 0 requested, 光标大小为 0
- android - 使用 AppCompat 时,我们是否需要明确指定其 UI 组件(Spinner、EditText)颜色
我正在尝试围绕不太完美的二值化矩形图像找到一个旋转的边界框。瑕疵总是不同的:有时它是空心的,有时里面有东西,有时其中一个边缘缺少一 block ,有时在边缘的某处有一个额外的 block ,它们总是稍微旋转一个随机的量,但大小预期边界框的形状总是几乎相同的像素绝对值。
这是我作为输入的一些示例(调整大小以更好地适应帖子):
理想情况下,我想在白色矩形的外部找到一个边界框(尽管我主要只对边缘感兴趣),如下所示:
(通过反转其中一个空心的,获得最大的连接组件,并获得强制尺寸的旋转方向找到)
到目前为止,我已经尝试只获取一个 rotatedrect 并在之后强制一个形状,这几乎适用于所有情况,除非沿着其中一个边缘有一个额外的 block 。我已经尝试获取连接的组件以隔离它的部分并在它们周围设置边界框,只要它们是空心的,它就适用于所有情况。我试过扩大和侵 eclipse 图像,获取轮廓和霍夫线以尝试仅找到四个角点,但我也没有运气。我也在网上寻找任何有用的东西但无济于事。
如有任何帮助或想法,我们将不胜感激。
最佳答案
我的解决方案包括两部分:
以下是演示此方法的简单程序。开头的参数(文件名、已知矩形的大小、角度搜索范围)通常会从命令行传入。
import cv2
import numpy as np
# arguments
file = '1.png'
w0, h0 = 425, 630 # size of known rectangle
ang_range = 1 # posible range (+/-) of angle in degrees
# read image
img = cv2.imread(file, cv2.IMREAD_GRAYSCALE)
h, w = img.shape
# find biggest connceted components
nb_components, output, stats, _ = cv2.connectedComponentsWithStats(img, connectivity=4)
sizes = stats[:, -1]
max_label, max_size = 1, sizes[1]
for i in range(2, nb_components):
if sizes[i] > max_size:
max_label = i
max_size = sizes[i]
img2 = np.zeros(img.shape, np.uint8)
img2[output == max_label] = 128
# fill holes
contours, _ = cv2.findContours(img2, cv2.RETR_CCOMP, cv2.CHAIN_APPROX_SIMPLE)
for contour in contours:
cv2.drawContours(img2, [contour], 0, 128, -1)
# find lines
edges = cv2.Canny(img2, 50, 150, apertureSize = 3)
lines = cv2.HoughLinesP(edges, 1, np.pi/180, 40)
# find bounding lines
xmax = ymax = 0
xmin, ymin = w-1, h-1
for i in range(lines.shape[0]):
x1 = lines[i][0][0]
y1 = lines[i][0][1]
x2 = lines[i][0][2]
y2 = lines[i][0][3]
cv2.line(img2, (x1,y1), (x2,y2), 255, 2, cv2.LINE_AA)
if abs(x1-x2) < abs(y1-y2):
# vertical line
xmin = min(xmin,x1,x2)
xmax = max(xmax,x1,x2)
else:
# horizcontal line
ymin = min(ymin,y1,y2)
ymax = max(ymax,y1,y2)
cv2.rectangle(img2, (xmin,ymin), (xmax,ymax), 255, 1, cv2.LINE_AA)
cv2.imwrite(file.replace('.png', '_intermediate.png'), img2)
# rectangle of known size centered at bounding box
xc = (xmax + xmin) / 2
yc = (ymax + ymin) / 2
box = np.zeros(img.shape, np.uint8)
box[int(yc-h0/2):int(yc+h0/2), int(xc-w0/2):int(xc+w0/2)] = 255
# find best match of this rectangle at different angles
smax = angmax = 0
for ang in np.linspace(-ang_range, ang_range, 20):
rm = cv2.getRotationMatrix2D((xc,yc), ang, 1)
rotbox = cv2.warpAffine(box, rm, (w,h))
s = cv2.countNonZero(cv2.bitwise_and(rotbox, img))
if s > smax:
smax = s
angmax = ang
# output and visualize result
def draw_rotated_rect(img, size, center, angle, color, thickness):
rm = cv2.getRotationMatrix2D(center, angle, 1)
p0 = np.dot(rm,(xc-w0/2, yc-h0/2,1))
p1 = np.dot(rm,(xc-w0/2, yc+h0/2,1))
p2 = np.dot(rm,(xc+w0/2, yc+h0/2,1))
p3 = np.dot(rm,(xc+w0/2, yc-h0/2,1))
pnts = np.int32(np.vstack([p0,p1,p2,p3]) + 0.5).reshape(-1,4,2)
cv2.polylines(img, pnts, True, color, thickness, cv2.LINE_AA)
print(f'{file}: edges {pnts[0].tolist()}, angle = {angle:.2f}°')
res = cv2.cvtColor(img, cv2.COLOR_GRAY2BGR)
draw_rotated_rect(res, (w0,h0), (xc,yc), angmax, (0,255,0), 2)
cv2.imwrite(file.replace('.png', '_result.png'), res)
显示其工作原理的中间结果(灰色 = 填充的最大连通分量,粗白线 = 霍夫线,细白色矩形 = 直立边界框):
(要查看全尺寸图片,请单击它们,然后删除文件扩展名前的最后一个 m
)
结果可视化(绿色 = 已知大小的旋转矩形):
结果(最终应该被clamp到[0,image size],-1是由于 float 旋转):
1.png: edges [[17, -1], [17, 629], [442, 629], [442, -1]], angle = 0.00°
2.png: edges [[7, 18], [9, 648], [434, 646], [432, 16]], angle = 0.26°
3.png: edges [[38, 25], [36, 655], [461, 657], [463, 27]], angle = -0.26°
4.png: edges [[36, 14], [28, 644], [453, 650], [461, 20]], angle = -0.79°
正如我们在图 3 中看到的,匹配并不完美。这可能是由于示例图像被缩小到略有不同的大小,当然我不知道已知矩形的大小,所以我只是为演示假设了一个合适的值。
如果真实数据也出现这种情况,您可能不仅需要改变角度以找到最佳匹配,而且还需要将匹配框向上/向下和向右/向左移动几个像素。例如参见 Dawson-Howe: A Practical Introduction to Computer Vision with OpenCV 的第 8.1 节了解更多详情。
关于python - 在带有噪声边的矩形周围找到已知大小的旋转边界框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57309118/
我目前有一堆看起来像这样的行: txt = "Can't print the value for "+arguments[1]+" before it's set"; 我在做 $('#mydiv').
我有一个网站,我试图以移动格式显示,但在宽屏幕上显示。我确信 iframe 是要走的路。 我正在尝试将 iframe 加载到 iPhone 的图像中。你可以看到一个例子 here . 一旦你看到它,你
我正在尝试使用 Xcode 中的 Storyboard创建如下所示的 View 。 为此,我添加了一个按钮和一个带有约束的标签,但这就是我得到的结果。文本不会从复选框下方开始。实现此目的的一种方法是创
我正在与 css 斗争以将文本包装在 div 中。我应用了空格、分词但没有任何反应。 链接 http://fiduciaryconsulting.org/index.php/services/90-s
关闭。这个问题需要debugging details .它目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and th
正如标题所说 - 如何将文本环绕在伪元素周围?请参见下面的示例: .area { position: relative; } .area:before { content: '';
每次我尝试在 CSS 中做一些看似简单的事情时,它都行不通。 我有一个包含 460x160 图像的内容 div。我想做的就是将图片放在右下角,然后用文字环绕它。 text text
每次我尝试在 CSS 中做一些看似简单的事情时,它都行不通。 我有一个包含 460x160 图像的内容 div。我想做的就是将图片放在右下角,然后用文字环绕它。 text text
我有一个流式布局,它已经为我工作了一段时间。我漂浮 不是右就是左。一个 div 通常会有一个图像和一个标题。 文本项正确地环绕在 float 周围。但是某些元素没有: 将做以下两件事之一:他们要么侵入
这是我的问题。我在另一个 div 中有内联 block div。 .timeEvents { width: 100%; overflow: hidden; text-align: cent
使用float,我可以让文本环绕figure标签中的图像,而不是环绕figcaption标签,因为出色地。将 float 添加到 figcaption 不会这样做。有什么建议吗? 下面的代码在这里:h
如何让 div 2 环绕 div 1 ? (两个 div 都包含文本) +---++------------------+ | || | | 1 ||
我有一个场景,我需要转换一个可以被 *this 链接的函数返回 std::optional>而不是 T& (原因超出了这个问题的范围)。我使用 std::reference_wrapper 的原因是因
我想我彻底搜索了这个网站,但找不到我的问题的答案;我也认为这很简单,但是经过几个小时的困惑之后,我已经放弃并决定寻求帮助...... 这是我的问题;我有一个 DIV,里面有两个 DIV;第一个 DIV
我有一个文本区域字段,其右上角有一个 div 框。我进行了广泛的搜索,但找不到一种方法可以让输入文本区域的文本环绕 div。 #wrapper { position: relative; wi
所以我在使用 FancyBox 时遇到了这个问题,当滚动页面主体(主页)时,框会随机向左和顶部移动位置。 附上 GIF 演示问题: 据我所知,我正在使用 Fancybox v2。 网址是here (在
我的 coinslider 周围有一个容器 div。我想围绕这个容器 div 包装文本。如何实现这一目标? 现在我的 HTML 设置如下: 我的 CSS 是这样设置的: #mycontain
每次我尝试在 CSS 中做一些看似简单的事情时,它都行不通。 我有一个包含 460x160 图像的内容 div。我想做的就是将图片放在右下角,然后用文字环绕它。 text text
我有一个名为“content”的 DIV,其中我有一个图像作为边框/框架,我想绕过它。我都有一个大的整个框架(左、右、上、下),它与它应该的宽度相匹配,而且我把它切碎了,所以我有四个单边框图像(lef
我正在使用 fieldset 在 div 周围创建带标题的边框。 这是代码: Sproc Details:
我是一名优秀的程序员,十分优秀!