Updating cropping checkpoint
Signed-off-by: Ethan Wellenreiter <ewellenreiter@gmail.com>
This commit is contained in:
parent
edeb73cca3
commit
fc2de6ed4f
@ -2,7 +2,7 @@
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 143,
|
||||
"execution_count": 20,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -15,17 +15,26 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 144,
|
||||
"execution_count": 21,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import os\n",
|
||||
"import pathlib\n",
|
||||
"\n",
|
||||
"def removeextensionandnumeric(filename):\n",
|
||||
" suffix = pathlib.Path(filename).suffix\n",
|
||||
" num = filename[:-len(suffix)]\n",
|
||||
" numint = int(num)\n",
|
||||
" return numint\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"def testondataset(pathtodataset, function):\n",
|
||||
" imagefileextensions = [\".jpg\", \".png\"]\n",
|
||||
" filenames = next(os.walk(pathtodataset), (None, None, []))[2]\n",
|
||||
" \n",
|
||||
" filenames.sort(key=removeextensionandnumeric)\n",
|
||||
" # print(filenames)\n",
|
||||
" outs = []\n",
|
||||
" for filename in filenames:\n",
|
||||
" suffix = pathlib.Path(filename).suffix\n",
|
||||
@ -40,7 +49,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 145,
|
||||
"execution_count": 22,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -62,31 +71,31 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 146,
|
||||
"execution_count": 23,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def writeimgs(directorypath, imgs):\n",
|
||||
" if (isinstance(imgs, np.ndarray)):\n",
|
||||
" cv2.imwrite(directorypath+\"test.jpg\", imgs)\n",
|
||||
" cv2.imwrite(directorypath+\"test.png\", imgs)\n",
|
||||
" else:\n",
|
||||
" for i, out in enumerate(imgs):\n",
|
||||
" cv2.imwrite(directorypath+\"test\"+str(i)+\".jpg\", out)"
|
||||
" cv2.imwrite(directorypath+\"test\"+str(i)+\".png\", out)"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 147,
|
||||
"execution_count": 24,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"img = cv2.imread('/mnt/dataset/baseimages/3.jpg')\n",
|
||||
"# img = cv2.imread('/mnt/code/autocropper/test_images/IMG_7594.jpg')"
|
||||
"img = cv2.imread('/mnt/dataset/baseimages/11.jpg')\n",
|
||||
"# img = cv2.imread('/mnt/code/autocropper/test_images/IMG_7605.jpg')"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 148,
|
||||
"execution_count": 25,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -106,33 +115,33 @@
|
||||
" # return thresh\n",
|
||||
"\n",
|
||||
" # dim = int(min(thresh.shape[0], thresh.shape[1])/400)\n",
|
||||
" # dim = 3\n",
|
||||
" # kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" # morphedthresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel)\n",
|
||||
" dim = 2\n",
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" morphedthresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel)\n",
|
||||
" # return morphedthresh\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" \n",
|
||||
" contours1, heirarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" # contours2, heirarchy = cv2.findContours(morphedthresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" contours2, heirarchy = cv2.findContours(morphedthresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" \n",
|
||||
"\n",
|
||||
"\n",
|
||||
" biggestcontour1 = max(contours1, key=cv2.contourArea)\n",
|
||||
" # biggestcontour2 = max(contours2, key=cv2.contourArea)\n",
|
||||
" biggestcontour2 = max(contours1, key=cv2.contourArea)\n",
|
||||
" biggestcontour1 = max(contours2, key=cv2.contourArea)\n",
|
||||
" \n",
|
||||
" epsilon = 0.0005*cv2.arcLength(biggestcontour1,True)\n",
|
||||
" approx = cv2.approxPolyDP(biggestcontour1,epsilon,True)\n",
|
||||
" # approx = cv2.convexHull(approx)\n",
|
||||
" epsilon = 0.001*cv2.arcLength(approx,True)\n",
|
||||
" epsilon = 0.005*cv2.arcLength(approx,True)\n",
|
||||
" approx = cv2.approxPolyDP(approx,epsilon,True)\n",
|
||||
" # approx = cv2.convexHull(biggestcontour1)\n",
|
||||
" # print(approx)\n",
|
||||
" \n",
|
||||
" # imagecpy = cv2.drawContours(imagecpy, [biggestcontour1], -1, (0,255,0), thickness=3)\n",
|
||||
" # imagecpy = cv2.drawContours(imagecpy, [biggestcontour2], -1, (0,0,255), thickness=3)\n",
|
||||
" imagecpy = cv2.drawContours(imagecpy, [biggestcontour1], -1, (0,255,0), thickness=3)\n",
|
||||
" imagecpy = cv2.drawContours(imagecpy, [biggestcontour2], -1, (0,0,255), thickness=3)\n",
|
||||
" \n",
|
||||
" # imagecpy = cv2.drawContours(imagecpy, [approx], -1, (0,255,0), thickness=3)\n",
|
||||
" imagecpy = cv2.drawContours(imagecpy, [approx], -1, (255,0,0), thickness=3)\n",
|
||||
" # return imagecpy\n",
|
||||
" \n",
|
||||
" blank = np.full(thresh.shape, 255, dtype=np.uint8)\n",
|
||||
@ -152,10 +161,19 @@
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" # invertmask = cv2.morphologyEx(invertmask, cv2.MORPH_DILATE, kernel)\n",
|
||||
" mask = 255 - cv2.morphologyEx(invertmask, cv2.MORPH_ERODE, kernel, iterations=1)\n",
|
||||
" # return mask\n",
|
||||
" return mask\n",
|
||||
" \n",
|
||||
" mask1 = cv2.cvtColor(mask, cv2.COLOR_GRAY2BGR)\n",
|
||||
" whitedbackground = cv2.bitwise_or(image, mask1)\n",
|
||||
" maskcontours, heirarchy = cv2.findContours(255-mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" \n",
|
||||
" mainmaskcontour = max(maskcontours, key=cv2.contourArea)\n",
|
||||
" mask1 = blank.copy()\n",
|
||||
" mask1 = cv2.drawContours(mask1, [mainmaskcontour], -1, (0,0,0), thickness=cv2.FILLED)\n",
|
||||
" mask1 = cv2.morphologyEx(mask1, cv2.MORPH_ERODE, kernel, iterations=1)\n",
|
||||
" # temp = cv2.drawContours(image, [mainmaskcontour], -1, (0,255,0), thickness=3)\n",
|
||||
" # return temp\n",
|
||||
" \n",
|
||||
" mask1c = cv2.cvtColor(mask1, cv2.COLOR_GRAY2BGR)\n",
|
||||
" whitedbackground = cv2.bitwise_or(image, mask1c)\n",
|
||||
" # return whitedbackground\n",
|
||||
" \n",
|
||||
" mask2 = blank.copy()\n",
|
||||
@ -163,10 +181,10 @@
|
||||
" \n",
|
||||
" dim = int(min(mask2.shape[0], mask2.shape[1])/50)\n",
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" morphedmask = 255-cv2.morphologyEx(mask2, cv2.MORPH_OPEN, kernel, iterations=3)\n",
|
||||
" morphedmask = 255-cv2.morphologyEx(mask2, cv2.MORPH_OPEN, kernel, iterations=7)\n",
|
||||
" # return morphedmask\n",
|
||||
" \n",
|
||||
" finalmask = cv2.bitwise_or(mask, morphedmask)\n",
|
||||
" finalmask = cv2.bitwise_or(mask1, morphedmask)\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" finalmaskbgr = cv2.cvtColor(finalmask, cv2.COLOR_GRAY2BGR)\n",
|
||||
@ -176,54 +194,18 @@
|
||||
" # return whitedbackground\n",
|
||||
" \n",
|
||||
" test = cv2.inpaint(whitedbackground, finalmask, 3, cv2.INPAINT_TELEA)\n",
|
||||
" return test\n",
|
||||
" \n",
|
||||
" \n",
|
||||
" \n",
|
||||
" \n",
|
||||
" gray2 = cv2.cvtColor(whitedbackground, cv2.COLOR_BGR2GRAY)\n",
|
||||
"\n",
|
||||
" canny = cv2.Canny(gray2, 0, 500, None, 3)\n",
|
||||
" \n",
|
||||
" maskgray = cv2.cvtColor(mask, cv2.COLOR_BGR2GRAY)\n",
|
||||
" \n",
|
||||
" \n",
|
||||
"\n",
|
||||
" invert = 255-maskgray\n",
|
||||
" # dim = 21\n",
|
||||
" # print(dim)\n",
|
||||
" dim = int(min(maskgray.shape[0], maskgray.shape[1])/200)\n",
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" morphedmask = cv2.morphologyEx(invert, cv2.MORPH_ERODE, kernel, iterations=2)\n",
|
||||
" dim = int(min(maskgray.shape[0], maskgray.shape[1])/50)\n",
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n",
|
||||
" morphedmask = cv2.morphologyEx(morphedmask, cv2.MORPH_OPEN, kernel, iterations=7)\n",
|
||||
" # return 255 - morphedmask\n",
|
||||
" morphedmask = 255 - morphedmask\n",
|
||||
"\n",
|
||||
" finalmask = cv2.bitwise_or(morphedmask, maskgray)\n",
|
||||
" # return finalmask\n",
|
||||
" \n",
|
||||
" # edgecontours, _ = cv2.findContours(255-morphedmask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" finalmaskbgr = cv2.cvtColor(finalmask, cv2.COLOR_GRAY2BGR)\n",
|
||||
" # return finalmaskbgr\n",
|
||||
"\n",
|
||||
" whitedbackground = cv2.bitwise_or(whitedbackground, finalmaskbgr)\n",
|
||||
" # return whitedbackground\n",
|
||||
" \n",
|
||||
" test = cv2.inpaint(whitedbackground, finalmask, 3, cv2.INPAINT_TELEA)\n",
|
||||
" return test"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 149,
|
||||
"execution_count": 26,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def cropclarifying(image):\n",
|
||||
" whitedbackground = whiteoutbackground(image)\n",
|
||||
" # return whitedbackground\n",
|
||||
" return whitedbackground\n",
|
||||
"\n",
|
||||
" textrefined = mf.textClarifying(whitedbackground)\n",
|
||||
" # return textrefined\n",
|
||||
@ -237,12 +219,102 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 150,
|
||||
"execution_count": 27,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def contourcrop(baseimage):\n",
|
||||
" shrunkencbi, sizemultiplier = mf.ResizeWithAspectRatio(baseimage, width=1000, retscale=True)\n",
|
||||
" gray = cv2.cvtColor(shrunkencbi, cv2.COLOR_BGR2GRAY)\n",
|
||||
" # thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1]\n",
|
||||
" thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_TRIANGLE)[1]\n",
|
||||
" # window = gray.shape[1]//7\n",
|
||||
" # if window % 2 == 0:\n",
|
||||
" # window += 1\n",
|
||||
" # thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window, 10)\n",
|
||||
"\n",
|
||||
" kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))\n",
|
||||
" # thresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel, iterations=2)\n",
|
||||
" thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)\n",
|
||||
" # return thresh\n",
|
||||
" \n",
|
||||
" contours, heirarchy = cv2.findContours(thresh,cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)\n",
|
||||
" \n",
|
||||
" # temp = cv2.drawContours(shrunkencbi, contours, -1, (0,255,0), thickness=3)\n",
|
||||
" # biggestcontour = max(contours, key=cv2.contourArea)\n",
|
||||
" # temp = cv2.drawContours(shrunkencbi, [biggestcontour], -1, (0,255,0), thickness=3)\n",
|
||||
" \n",
|
||||
" # return temp\n",
|
||||
" \n",
|
||||
" mx = (0,0,0,0)\n",
|
||||
" mx_area = 0\n",
|
||||
"\n",
|
||||
" for i, cont in enumerate(contours):\n",
|
||||
" rect = cv2.boundingRect(cont)\n",
|
||||
" area = mf.rectArea(rect)\n",
|
||||
" if (area > mx_area):\n",
|
||||
" mx = rect\n",
|
||||
" mx_area = area\n",
|
||||
"\n",
|
||||
" \n",
|
||||
" scaledmx = (int(mx[0]*sizemultiplier), int(mx[1]*sizemultiplier), int(mx[2]*sizemultiplier), int(mx[3]*sizemultiplier))\n",
|
||||
" finalbaseimage = baseimage[scaledmx[1]:scaledmx[1]+scaledmx[3], scaledmx[0]:scaledmx[0]+scaledmx[2], :]\n",
|
||||
" return finalbaseimage"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 28,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def houghlinedeskewthencrop(baseimage, preppedimage, rotationangle):\n",
|
||||
" rotateddst1 = mf.rotatewithexactpadding(preppedimage, rotationangle, fill=0)\n",
|
||||
" rotatedbaseimage = mf.rotatewithexactpadding(baseimage, rotationangle, fill=(0,0,0))\n",
|
||||
" sizemultiplier = rotatedbaseimage.shape[0]/rotateddst1.shape[0]\n",
|
||||
" # print(sizemultiplier)\n",
|
||||
" # return rotatedbaseimage, rotationangle\n",
|
||||
"\n",
|
||||
" croppedbaseimage = mf.houghlinepcrop(rotatedbaseimage, rotateddst1, sizemultiplier)\n",
|
||||
" # return croppedbaseimage, rotationangle\n",
|
||||
"\n",
|
||||
" finalbaseimage = contourcrop(croppedbaseimage)\n",
|
||||
"\n",
|
||||
"\n",
|
||||
" return finalbaseimage, rotationangle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 29,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def houghlinedeskewandcrop(image):\n",
|
||||
" canny, croppedogimage = mf.prepimageforhoughline(image) ## scaling and cropping occurs. need to also return the changes done\n",
|
||||
" # return croppedogimage, canny\n",
|
||||
" # print(canny.shape)\n",
|
||||
" # print(croppedogimage.shape)\n",
|
||||
"\n",
|
||||
" ## -----------------finding angle to deskew-----------------\n",
|
||||
" rotationangle = mf.houghlinedeskewangle(canny)\n",
|
||||
" # print(rotationangle)\n",
|
||||
"\n",
|
||||
" # -----------------end of finding angle to deskew-----------------\n",
|
||||
"\n",
|
||||
" ## -----------------deskewing and then cropping-----------------\n",
|
||||
" outimg, angle = houghlinedeskewthencrop(croppedogimage, canny, rotationangle)\n",
|
||||
" return outimg, angle"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 30,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"def houghlineprocessing(image):\n",
|
||||
" croppedanddeskewed, _ = mf.houghlinedeskewandcrop(image)\n",
|
||||
" croppedanddeskewed, angle = houghlinedeskewandcrop(image)\n",
|
||||
" return croppedanddeskewed\n",
|
||||
" \n",
|
||||
" \n",
|
||||
@ -268,12 +340,13 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 151,
|
||||
"execution_count": 31,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"# prepped, scaler, hp, vp = mf.squareandthenresize(img, fill=255, width=1000, returnscalerinfo=True)\n",
|
||||
"outs = houghlineprocessing(img)\n",
|
||||
"# print(img.shape)\n",
|
||||
"# outs = houghlinedeskewandcrop(img)\n",
|
||||
"# outs = outs[0]\n",
|
||||
"# print(croprect)\n",
|
||||
@ -282,7 +355,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 152,
|
||||
"execution_count": 32,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -296,7 +369,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 153,
|
||||
"execution_count": 33,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -308,7 +381,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 154,
|
||||
"execution_count": 34,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -317,7 +390,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 155,
|
||||
"execution_count": 35,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -347,7 +420,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 156,
|
||||
"execution_count": 36,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -356,7 +429,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 157,
|
||||
"execution_count": 37,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
@ -365,7 +438,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 158,
|
||||
"execution_count": 38,
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
|
||||
@ -91,6 +91,11 @@ def mergecontours(contours):
|
||||
finalcontour = cv2.convexHull(cont)
|
||||
return finalcontour
|
||||
|
||||
def padWithColour(img, hpadding=0, vpadding=0, fill=(0,0,0)):
|
||||
borderType = cv2.BORDER_CONSTANT
|
||||
out = cv2.copyMakeBorder(img, vpadding, vpadding, hpadding, hpadding, borderType, None, fill)
|
||||
return out
|
||||
|
||||
|
||||
# funtion to correct the median-angle to give it to the cv2.warpaffine() function
|
||||
# specifically, when getting the angle from a minAreaRect rectangle
|
||||
@ -344,7 +349,10 @@ def rotateLine(img, line, angle, returnint=True):
|
||||
def prepimageforhoughline(image):
|
||||
prepped, scaler, hp, vp = squareandthenresize(image, fill=255, width=1000, returnscalerinfo=True)
|
||||
prepped, croprect = premorphCrop(prepped)
|
||||
prepped = squareandthenresize(prepped, fill=255, width=1000)
|
||||
if (prepped.shape[1] > prepped.shape[0]):
|
||||
prepped = ResizeWithAspectRatio(prepped, width=1000)
|
||||
else:
|
||||
prepped = ResizeWithAspectRatio(prepped, height=1000)
|
||||
finalcroprect = (int(croprect[0]*scaler - hp), int(croprect[1]*scaler - vp), int(croprect[2]*scaler), int(croprect[3]*scaler))
|
||||
gray1 = cv2.cvtColor(prepped, cv2.COLOR_BGR2GRAY)
|
||||
|
||||
@ -361,7 +369,7 @@ def prepimageforhoughline(image):
|
||||
dst1 = cv2.Canny(dst1, 0, 500, None, 3)
|
||||
# return dst1
|
||||
accompaniedimage = image[finalcroprect[1]:finalcroprect[1]+finalcroprect[3], finalcroprect[0]:finalcroprect[0]+finalcroprect[2], :]
|
||||
accompaniedimage = squarepad(accompaniedimage, fill=255)
|
||||
# accompaniedimage = squarepad(accompaniedimage, fill=255)
|
||||
return dst1, accompaniedimage
|
||||
|
||||
def houghlinedeskewangle(image):
|
||||
@ -391,56 +399,94 @@ def houghlinedeskewangle(image):
|
||||
rotationangle = np.rad2deg(mode)
|
||||
return rotationangle
|
||||
|
||||
def houghlinedeskewthencrop(baseimage, preppedimage, rotationangle):
|
||||
rotateddst1 = rotate(preppedimage, rotationangle)
|
||||
rotatedbaseimage = rotate(baseimage, rotationangle)
|
||||
sizemultiplier = rotatedbaseimage.shape[0]/rotateddst1.shape[0]
|
||||
# print(sizemultiplier)
|
||||
|
||||
|
||||
linesP = cv2.HoughLinesP(preppedimage, 1, np.pi / 180, 30, None, 90, 30)
|
||||
|
||||
|
||||
rotatedlines = [rotateLine(rotateddst1, line[0], rotationangle) for line in linesP]
|
||||
rotatedlines = np.reshape(rotatedlines, (len(rotatedlines),1,4))
|
||||
def determineextrapadding(img, angle):
|
||||
h, w = img.shape[0], img.shape[1]
|
||||
radangle = abs(np.deg2rad(angle))
|
||||
# print(radangle)
|
||||
totalheightrot = w*np.sin(radangle) + h*np.cos(radangle)
|
||||
# print(h, totalheightrot)
|
||||
totalwidthrot = h*np.sin(radangle) + w*np.cos(radangle)
|
||||
# print(w, totalwidthrot)
|
||||
vpad = int(max(0,math.ceil((totalheightrot - h)/2)))
|
||||
hpad = int(max(0,math.ceil((totalwidthrot-w)/2)))
|
||||
# print(vpad, hpad)
|
||||
return hpad, vpad
|
||||
|
||||
def rotatewithexactpadding(img, angle, fill=(0,0,0)):
|
||||
hpad, vpad = determineextrapadding(img, angle)
|
||||
baseimage = padWithColour(img, hpad, vpad, fill=fill)
|
||||
rotatedimg = rotate(baseimage, angle)
|
||||
return rotatedimg
|
||||
|
||||
def houghlinepcrop(baseimage, preppedimage, scalingmultiplier):
|
||||
rotatedlines = cv2.HoughLinesP(preppedimage, 1, np.pi / 180, 30, None, 90, 30)
|
||||
|
||||
vmarginlines = WithinXDegrees(rotatedlines, 7)
|
||||
hmarginlines = WithinXDegrees(rotatedlines, 7, baseangle=90)
|
||||
vrect = lineBoundingRect(vmarginlines,asRect=False, returnint=True)
|
||||
hmarginlines = lineswithinrange(hmarginlines, (vrect[0], vrect[1]), (vrect[2],vrect[3]), x=True, y=False)
|
||||
|
||||
if (hmarginlines != []):
|
||||
marginlines = np.append(vmarginlines, hmarginlines, axis=0)
|
||||
else:
|
||||
marginlines = vmarginlines
|
||||
|
||||
# print(marginlines)
|
||||
rect = lineBoundingRect(marginlines,asRect=False, returnint=True)
|
||||
# print(rect)
|
||||
scaledrect = (int(rect[0]*sizemultiplier), int(rect[1]*sizemultiplier), int(rect[2]*sizemultiplier), int(rect[3]*sizemultiplier))
|
||||
|
||||
croppedbaseimage = rotatedbaseimage[scaledrect[1]:scaledrect[3], scaledrect[0]:scaledrect[2], :]
|
||||
# vrect = lineBoundingRect(vmarginlines,asRect=False, returnint=True)
|
||||
# hmarginlines = lineswithinrange(hmarginlines, (vrect[0], vrect[1]), (vrect[2],vrect[3]), x=True, y=False)
|
||||
marginlines = np.append(vmarginlines, hmarginlines, axis=0)
|
||||
|
||||
# colourdst = cv2.cvtColor(preppedimage, cv2.COLOR_GRAY2BGR)
|
||||
# if marginlines is not None:
|
||||
# for l in marginlines:
|
||||
# cv2.line(colourdst, (int(l[0]), int(l[1])), (int(l[2]), int(l[3])), (0,0,255), 3, cv2.LINE_AA)
|
||||
# return colourdst
|
||||
|
||||
rect = lineBoundingRect(marginlines,asRect=False, returnint=True)
|
||||
scaledrect = (int(rect[0]*scalingmultiplier), int(rect[1]*scalingmultiplier), int(rect[2]*scalingmultiplier), int(rect[3]*scalingmultiplier))
|
||||
croppedbaseimage = baseimage[scaledrect[1]:scaledrect[3], scaledrect[0]:scaledrect[2], :]
|
||||
return croppedbaseimage
|
||||
|
||||
# print(croppedbaseimage.shape)
|
||||
shrunkencbi, sizemultiplier = ResizeWithAspectRatio(croppedbaseimage, width=1000, retscale=True)
|
||||
def contourcrop(baseimage):
|
||||
shrunkencbi, sizemultiplier = mf.ResizeWithAspectRatio(baseimage, width=1000, retscale=True)
|
||||
gray = cv2.cvtColor(shrunkencbi, cv2.COLOR_BGR2GRAY)
|
||||
thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1]
|
||||
# thresh = cv2.threshold(gray, 200, 255, cv2.THRESH_BINARY)[1]
|
||||
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_TRIANGLE)[1]
|
||||
# window = gray.shape[1]//7
|
||||
# if window % 2 == 0:
|
||||
# window += 1
|
||||
# thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window, 10)
|
||||
|
||||
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5,5))
|
||||
# thresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel, iterations=2)
|
||||
thresh = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel)
|
||||
# return thresh
|
||||
|
||||
contours, heirarchy = cv2.findContours(thresh,cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
|
||||
|
||||
# temp = cv2.drawContours(shrunkencbi, contours, -1, (0,255,0), thickness=3)
|
||||
# biggestcontour = max(contours, key=cv2.contourArea)
|
||||
# temp = cv2.drawContours(shrunkencbi, [biggestcontour], -1, (0,255,0), thickness=3)
|
||||
|
||||
# return temp
|
||||
|
||||
mx = (0,0,0,0)
|
||||
mx_area = 0
|
||||
|
||||
for i, cont in enumerate(contours):
|
||||
rect = cv2.boundingRect(cont)
|
||||
area = rectArea(rect)
|
||||
area = mf.rectArea(rect)
|
||||
if (area > mx_area):
|
||||
mx = rect
|
||||
mx_area = area
|
||||
|
||||
|
||||
scaledmx = (int(mx[0]*sizemultiplier), int(mx[1]*sizemultiplier), int(mx[2]*sizemultiplier), int(mx[3]*sizemultiplier))
|
||||
finalbaseimage = croppedbaseimage[scaledmx[1]:scaledmx[1]+scaledmx[3], scaledmx[0]:scaledmx[0]+scaledmx[2], :]
|
||||
finalbaseimage = baseimage[scaledmx[1]:scaledmx[1]+scaledmx[3], scaledmx[0]:scaledmx[0]+scaledmx[2], :]
|
||||
return finalbaseimage
|
||||
|
||||
def houghlinedeskewthencrop(baseimage, preppedimage, rotationangle):
|
||||
rotateddst1 = rotatewithexactpadding(preppedimage, rotationangle, fill=0)
|
||||
rotatedbaseimage = rotatewithexactpadding(baseimage, rotationangle, fill=(0,0,0))
|
||||
sizemultiplier = rotatedbaseimage.shape[0]/rotateddst1.shape[0]
|
||||
# print(sizemultiplier)
|
||||
# return rotatedbaseimage, rotationangle
|
||||
|
||||
croppedbaseimage = houghlinepcrop(rotatedbaseimage, rotateddst1, sizemultiplier)
|
||||
|
||||
finalbaseimage = contourcrop(croppedbaseimage)
|
||||
|
||||
|
||||
return finalbaseimage, rotationangle
|
||||
|
||||
@ -457,8 +503,8 @@ def houghlinedeskewandcrop(image):
|
||||
# -----------------end of finding angle to deskew-----------------
|
||||
|
||||
## -----------------deskewing and then cropping-----------------
|
||||
|
||||
return houghlinedeskewthencrop(croppedogimage, canny, rotationangle)
|
||||
outimg, angle = houghlinedeskewthencrop(croppedogimage, canny, rotationangle)
|
||||
return outimg, angle
|
||||
|
||||
def bruteforceprocessrects(greaterrects, lesserrects):
|
||||
# squaredgrects = np.array([mf.xywhrectto2prect(rect) for rect in greaterrects])
|
||||
@ -1066,7 +1112,7 @@ def receipttextdeskew(img, fill=(0,0,0)):
|
||||
|
||||
## ------------------------------Full deskewing and cropping------------------------------
|
||||
def houghlineprocessing(image):
|
||||
croppedanddeskewed, _ = houghlinedeskewandcrop(image)
|
||||
croppedanddeskewed, angle = houghlinedeskewandcrop(image)
|
||||
|
||||
postprocessed = cropclarifying(croppedanddeskewed)
|
||||
# return postprocessed
|
||||
|
||||
Loading…
Reference in New Issue
Block a user