First implementation of houghline cropping/deskewing

Still need to fix threshold/morphology so that the bed
picture works.

Signed-off-by: Ethan Wellenreiter <ewellenreiter@gmail.com>
This commit is contained in:
Ethan Wellenreiter 2023-10-08 13:43:44 -04:00
parent d5e7a2eed2
commit 5bd770da55

View File

@ -2,7 +2,7 @@
"cells": [
{
"cell_type": "code",
"execution_count": 264,
"execution_count": 335,
"metadata": {},
"outputs": [],
"source": [
@ -13,7 +13,7 @@
},
{
"cell_type": "code",
"execution_count": 265,
"execution_count": 336,
"metadata": {},
"outputs": [],
"source": [
@ -26,7 +26,7 @@
},
{
"cell_type": "code",
"execution_count": 266,
"execution_count": 337,
"metadata": {},
"outputs": [],
"source": [
@ -74,29 +74,121 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 338,
"metadata": {},
"outputs": [],
"source": [
"def morphologyCrop(image):\n",
" # convert to grayscale\n",
" gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)\n",
"\n",
" # threshold\n",
" thresh = cv2.threshold(gray, 170, 255, cv2.THRESH_BINARY)[1]\n",
"\n",
" # apply morphology\n",
" kernel = np.ones((7,7), np.uint8)\n",
" morph = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)\n",
" kernel = np.ones((9,9), np.uint8)\n",
" morph = cv2.morphologyEx(morph, cv2.MORPH_ERODE, kernel)\n",
"\n",
" # get largest contour\n",
" contours = cv2.findContours(morph, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)\n",
" contours = contours[0] if len(contours) == 2 else contours[1]\n",
" area_thresh = 0\n",
" for c in contours:\n",
" area = cv2.contourArea(c)\n",
" if area > area_thresh:\n",
" area_thresh = area\n",
" big_contour = c\n",
"\n",
"\n",
" # get bounding box\n",
" x,y,w,h = cv2.boundingRect(big_contour)\n",
"\n",
" # draw filled contour on black background\n",
" mask = np.zeros_like(gray)\n",
" mask = cv2.merge([mask,mask,mask])\n",
" cv2.drawContours(mask, [big_contour], -1, (255,255,255), cv2.FILLED)\n",
"\n",
" # apply mask to input\n",
" result1 = image.copy()\n",
" result1 = cv2.bitwise_and(result1, mask)\n",
"\n",
" # crop result\n",
" result2 = result1[y:y+h, x:x+w]\n",
" return result2"
]
},
{
"cell_type": "code",
"execution_count": 339,
"metadata": {},
"outputs": [],
"source": [
"\n",
"# x = -2*np.pi/3\n",
"# print(x)\n",
"# print(np.pi/3)\n",
"# print(x % np.pi)"
]
},
{
"cell_type": "code",
"execution_count": 340,
"metadata": {},
"outputs": [],
"source": [
"def lineAngle(line):\n",
" # print(line)\n",
" angle = (math.atan2(line[3] - line[1], line[2] - line[0]) % np.pi) - (np.pi/2)\n",
" return angle\n",
" \n",
"def WithinXDegrees(lines, margin):\n",
" # outlines = np.array([[]])\n",
" outlines = np.empty((0, 4))\n",
" # print(outlines.shape)\n",
" for line in lines:\n",
" if ()"
" # print(type(line))\n",
" # print(abs(lineAngle(line[0])))\n",
" if (np.rad2deg(abs(lineAngle(line[0]))) <= margin):\n",
" outlines = np.append(outlines, [line[0]], axis=0)\n",
" return outlines\n",
"\n",
"def lineBoundingRect(lines):\n",
" maxvals = lines.max(0)\n",
" minvals = lines.min(0)\n",
" boundingrect = (min(minvals[0],minvals[2]), min(minvals[1],minvals[3]), max(maxvals[0],maxvals[2]),max(maxvals[1],maxvals[3]))\n",
" return boundingrect\n",
" # print(lines.max(0))\n",
" # print(type(lines))"
]
},
{
"cell_type": "code",
"execution_count": 267,
"execution_count": 341,
"metadata": {},
"outputs": [],
"source": [
"img = cv2.imread('./testing_space/final.jpg')\n",
"img = cv2.imread('./test_images/IMG_7605.jpg')\n",
"img = SquarePad(fill=255)(img)\n",
"img = rotate(img, 54)"
"img = rotate(img, 54)\n",
"img = morphologyCrop(img)"
]
},
{
"cell_type": "code",
"execution_count": 268,
"execution_count": 342,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", ResizeWithAspectRatio(SquarePad(fill=255)(img), 500))\n",
"cv2.waitKey(0)\n",
"cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": 343,
"metadata": {},
"outputs": [],
"source": [
@ -116,7 +208,7 @@
},
{
"cell_type": "code",
"execution_count": 269,
"execution_count": 344,
"metadata": {},
"outputs": [],
"source": [
@ -135,21 +227,24 @@
" pt2 = (int(unroundedpt2[0]), int(unroundedpt2[1]))\n",
" v1_theta = math.atan2(pt1[1], pt1[0])\n",
" v2_theta = math.atan2(pt2[1], pt2[0])\n",
" angles[i] = abs(math.atan2(unroundedpt2[1] - unroundedpt1[1], unroundedpt2[0] - unroundedpt1[0]))\n",
" # print(math.atan2(unroundedpt2[1] - unroundedpt1[1], unroundedpt2[0] - unroundedpt1[0]) % np.pi)\n",
" # print(lineAngle((unroundedpt1[0], unroundedpt1[1], unroundedpt2[0], unroundedpt2[1])))\n",
" # angles[i] = math.atan2(unroundedpt2[1] - unroundedpt1[1], unroundedpt2[0] - unroundedpt1[0]) % np.pi\n",
" angles[i] = lineAngle((unroundedpt1[0], unroundedpt1[1], unroundedpt2[0], unroundedpt2[1]))\n",
" cv2.line(cdst, pt1, pt2, (0,0,255), 3, cv2.LINE_AA)"
]
},
{
"cell_type": "code",
"execution_count": 270,
"execution_count": 345,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"34.95042550298022\n",
"-55.04957449701978\n"
"-45.26366581533504\n",
"-45.26366581533504\n"
]
}
],
@ -168,68 +263,70 @@
"# p2[1] = int(p2[1])\n",
"# print(p2)\n",
"# cv2.line(cdst, p1, p2, (0,255,0), 3, cv2.LINE_AA)\n",
"rotationangle = np.rad2deg(mode)-90\n",
"# rotationangle = np.rad2deg(mode)-90\n",
"rotationangle = np.rad2deg(mode)\n",
"print(rotationangle)"
]
},
{
"cell_type": "code",
"execution_count": 271,
"execution_count": 346,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", cdst)\n",
"cv2.waitKey(0)\n",
"cv2.destroyAllWindows()"
"# cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", cdst)\n",
"# cv2.waitKey(0)\n",
"# cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": 272,
"execution_count": 347,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", rotate(cdst,rotationangle))\n",
"cv2.waitKey(0)\n",
"cv2.destroyAllWindows()"
"# cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", rotate(cdst,rotationangle))\n",
"# cv2.waitKey(0)\n",
"# cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": 273,
"execution_count": 348,
"metadata": {},
"outputs": [],
"source": [
"rotatedimg = SquarePad(fill=255)(rotate(img, rotationangle))"
"rotatedimg = SquarePad(fill=255)(rotate(img, rotationangle))\n"
]
},
{
"cell_type": "code",
"execution_count": 274,
"execution_count": 349,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Rotated Image\", ResizeWithAspectRatio(rotatedimg, 1000))\n",
"cv2.waitKey(0)\n",
"cv2.destroyAllWindows()"
"# cv2.imshow(\"Rotated Image\", ResizeWithAspectRatio(rotatedimg, 1000))\n",
"# cv2.waitKey(0)\n",
"# cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": 302,
"execution_count": 350,
"metadata": {},
"outputs": [],
"source": [
"resizedrotatedimg = ResizeWithAspectRatio(rotatedimg, 500)\n",
"gray1 = cv2.cvtColor(resizedrotatedimg, cv2.COLOR_BGR2GRAY)\n",
"dst1 = cv2.Canny(gray1, 50, 200, None, 3)\n",
"dst1 = cv2.Canny(gray1, 0, 500, None, 3)\n",
"cdstP = resizedrotatedimg.copy()\n",
"linesP = cv2.HoughLinesP(dst1, 1, np.pi / 180, 50, None, 50, 30)"
"cdstPmargin = cdstP.copy()\n",
"linesP = cv2.HoughLinesP(dst1, 1, np.pi / 180, 30, None, 100, 30)"
]
},
{
"cell_type": "code",
"execution_count": 303,
"execution_count": 351,
"metadata": {},
"outputs": [],
"source": [
@ -241,11 +338,49 @@
},
{
"cell_type": "code",
"execution_count": 305,
"execution_count": 352,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", cdstP)\n",
"# cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", cdstP)\n",
"# cv2.waitKey(0)\n",
"# cv2.destroyAllWindows()"
]
},
{
"cell_type": "code",
"execution_count": 353,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"(274.0, 75.0, 355.0, 458.0)\n"
]
}
],
"source": [
"# print(linesP)\n",
"marginlines = WithinXDegrees(linesP, 2)\n",
"# print(marginlines)\n",
"# if marginlines is not None:\n",
"# for i in range(0, len(marginlines)):\n",
"# l = marginlines[i]\n",
"# cv2.line(cdstPmargin, (int(l[0]), int(l[1])), (int(l[2]), int(l[3])), (0,0,255), 3, cv2.LINE_AA)\n",
" \n",
"boundingrectout = lineBoundingRect(marginlines)\n",
"print(boundingrectout)\n",
"cdstPmargin = cv2.rectangle(cdstPmargin,(int(boundingrectout[0]),int(boundingrectout[1])),(int(boundingrectout[2]),int(boundingrectout[3])),(0,255,0),2)"
]
},
{
"cell_type": "code",
"execution_count": 354,
"metadata": {},
"outputs": [],
"source": [
"cv2.imshow(\"Detected Lines (in red) - Standard Hough Line Transform\", cdstPmargin)\n",
"cv2.waitKey(0)\n",
"cv2.destroyAllWindows()"
]