为了账号安全,请及时绑定邮箱和手机立即绑定

旋转不完整的盒子,使其垂直

旋转不完整的盒子,使其垂直

心有法竹 2022-07-19 15:26:57
我有一个 X 射线图像数据集,我试图通过旋转图像来清理它,使手臂垂直并裁剪任何多余空间的图像。以下是数据集中的一些示例:我目前正在研究计算 X 射线角度并以此为基础旋转图像的最佳方法。我目前的方法是使用霍夫变换检测扫描所在的矩形边的线,并以此为基础旋转图像。我试图在精明的边缘检测器的输出上运行霍夫变换,但这对于矩形边缘像第一张图像一样模糊的图像效果不佳。我不能使用 cv 的框检测,因为有时扫描周围的矩形有一个边缘离开屏幕。所以我目前使用自适应阈值来找到框的边缘,然后对其进行中值滤波并尝试在其中找到最长的线,但有时错误的线是最长的,并且图像被旋转完全错误。由于某些扫描具有不同的亮度,因此使用了自适应阈值。我目前的实现是:def get_lines(img):  #threshold  thresh = cv2.adaptiveThreshold(img, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 15, 4.75)  median = cv2.medianBlur(thresh, 3)  # detect lines  lines = cv2.HoughLines(median, 1, np.pi/180, 175)  return sorted(lines, key=lambda x: x[0][0], reverse=True)def rotate(image, angle):  (h, w) = image.shape[:2]  (cX, cY) = (w // 2, h // 2)  M = cv2.getRotationMatrix2D((cX, cY), angle, 1.0)  cos = np.abs(M[0, 0])  sin = np.abs(M[0, 1])  nW = int((h * sin) + (w * cos))  nH = int((h * cos) + (w * sin))  M[0, 2] += (nW / 2) - cX  M[1, 2] += (nH / 2) - cY  return cv2.warpAffine(image, M, (nW, nH))def fix_rotation(input):  lines = get_lines(input)  rho, theta = lines[0][0]  return rotate_bound(input, theta*180/np.pi)并产生以下结果:出错时:我想知道是否有任何更好的技术可以使用以提高性能,以及在旋转图像后裁剪图像的最佳方法是什么?
查看完整描述

2 回答

?
青春有我

TA贡献1784条经验 获得超8个赞

这个想法是使用手臂本身的斑点并在其周围放置一个椭圆。然后,提取其主轴。我很快在Matlab中测试了这个想法——而不是 OpenCV。这是我所做的,您应该能够使用 OpenCV 的等效函数来实现类似的输出。


首先,通过 Otsu 计算输入的阈值。然后对阈值添加一些偏差以找到更好的分割并使用该值对图像进行阈值处理。


在伪代码中:


//the bias value

threshBias = 0.4;


//get the binary threshold via otsu: 

thresholdLevel = graythresh( grayInput, “otsu” );


//add bias to the original value

thresholdLevel = thresholdLevel - threshSensitivity * thresholdLevel;


//get the fixed binary image: 

thresholdLevel = imbinarize( grayInput, thresholdLevel );

经过小斑点过滤后,这是输出:

在此处输入图像描述

现在,获取轮廓/斑点并为每个轮廓拟合一个椭圆。在此处查看 OpenCV 示例:https ://docs.opencv.org/3.4.9/de/d62/tutorial_bounding_rotated_ellipses.html

你最终得到两个椭圆:

在此处输入图像描述

我们正在寻找最大的椭圆,即面积最大、长轴和短轴最大的椭圆。我使用每个椭圆的宽度和高度来过滤结果。然后将目标椭圆着色为绿色。最后,我得到了目标椭圆的长轴,这里用黄色着色:

在此处输入图像描述

现在,要在OpenCV中实现这些想法,您有以下选择:

  • 用于fitEllipse查找椭圆。这个函数的返回值是一个RotatedRect对象。这里存储的数据是椭圆的顶点。

  • 您可以尝试使用 代替拟合椭圆minAreaRect,它会找到一个包含一个 blob 的最小区域的旋转矩形。


查看完整回答
反对 回复 2022-07-19
?
幕布斯6054654

TA贡献1876条经验 获得超7个赞

您可以使用图像矩来计算旋转角度。使用 opencv函数,计算二阶中心矩以构造协方差矩阵,然后获得方向,如Image moment wiki 页面中所示。获得归一化中心矩,并从 opencv 。然后方向计算为nu20nu11nu02moments

0.5 * arctan(2 * nu11/(nu20 - nu02))

有关详细信息,请参阅给定的链接。

您可以使用原始图像本身或预处理的图像来计算方向。看看哪一个可以为您提供更好的准确性并使用它。

至于边界框,一旦旋转图像,假设您使用了预处理的图像,获取旋转图像的所有非零像素坐标并使用 opencv boundingRect计算它们的垂直边界框。



查看完整回答
反对 回复 2022-07-19
  • 2 回答
  • 0 关注
  • 113 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号