diff --git a/code/autocropper/houghlinedevspace.ipynb b/code/autocropper/houghlinedevspace.ipynb index 7d02e20..585ffd6 100644 --- a/code/autocropper/houghlinedevspace.ipynb +++ b/code/autocropper/houghlinedevspace.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 3033, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -15,7 +15,7 @@ }, { "cell_type": "code", - "execution_count": 3034, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -55,7 +55,7 @@ }, { "cell_type": "code", - "execution_count": 3035, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -77,7 +77,7 @@ }, { "cell_type": "code", - "execution_count": 3036, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -91,25 +91,28 @@ }, { "cell_type": "code", - "execution_count": 3037, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ - "img = cv2.imread('/mnt/dataset/baseimages/12.jpg')\n", + "img = cv2.imread('/mnt/dataset/baseimages/15.jpg')\n", "# img = cv2.imread('/mnt/code/autocropper/test_images/IMG_7605.jpg')\n", "testall = False" ] }, { "cell_type": "code", - "execution_count": 3038, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ + "## NEED TO FIX THE EARLIER PARTS SO THAT IT DOESN'T HAVE THOSE BLACK SECTIONS AFTER THE ROTATION\n", + "\n", + "\n", "def whiteoutbackground(image):\n", " sdim = int(min(image.shape[0], image.shape[1])/10)\n", - " skernel = cv2.getStructuringElement(cv2.MORPH_RECT, (sdim, sdim))\n", - " srkernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (sdim, sdim))\n", + " srkernel = cv2.getStructuringElement(cv2.MORPH_RECT, (sdim, sdim))\n", + " skernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (sdim, sdim))\n", " \n", " \n", " lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)\n", @@ -129,7 +132,7 @@ " blurimage1 = cv2.blur(laba, (5,5))\n", " blurimage2 = cv2.blur(labb, (5,5))\n", " \n", - " window = lab.shape[1]//5\n", + " window = lab.shape[1]//3\n", " if window % 2 == 0:\n", " window += 1\n", " thresh1 = cv2.adaptiveThreshold(blurimage1, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window, 0)\n", @@ -137,10 +140,12 @@ " if window % 2 == 0:\n", " window += 1\n", " thresh2 = cv2.adaptiveThreshold(blurimage2, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window, 0)\n", + " # return thresh1\n", " imglist.append(thresh1)\n", " imglist.append(thresh2)\n", " threshmerge = cv2.bitwise_or(thresh1, thresh2)\n", " imglist.append(threshmerge)\n", + " # return threshmerge\n", " \n", " dim = int(min(threshmerge.shape[0], threshmerge.shape[1])/100)\n", " # dim = 2\n", @@ -151,6 +156,7 @@ " mask1t = cv2.morphologyEx(padthresh, cv2.MORPH_OPEN, kernel, iterations=1)\n", " # mask1t = cv2.morphologyEx(mask1t, cv2.MORPH_OPEN, skernel)\n", " imglist.append(mask1t)\n", + " # return mask1t\n", " \n", " contours, heirarchy = cv2.findContours(255-mask1t, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", " biggestcontour = max(contours, key=cv2.contourArea)\n", @@ -162,13 +168,15 @@ " # temp = cv2.drawContours(image, [biggestcontour], -1, 255, thickness=3)\n", " # imglist.append(temp)\n", " imglist.append(mask1)\n", + " # return mask1\n", " \n", - " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, srkernel, iterations=2)\n", + " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel, iterations=2)\n", " # mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel, iterations=2)\n", - " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, srkernel)\n", + " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, skernel)\n", " # mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel, iterations=2)\n", " mask1 = mask1[sdim:-sdim, sdim:-sdim]\n", " imglist.append(mask1)\n", + " # return mask1\n", " \n", " maskc = cv2.cvtColor(mask1, cv2.COLOR_GRAY2BGR)\n", " whitedbackground = cv2.bitwise_or(image, maskc)\n", @@ -180,38 +188,6 @@ " \n", " \n", " \n", - " # contours, heirarchy = cv2.findContours(255-threshmerge, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", - " # biggestcontour = max(contours, key=cv2.contourArea)\n", - " \n", - " # blank = np.full(threshmerge.shape, 255, dtype=np.uint8)\n", - " # mask1 = blank.copy()\n", - " # mask1 = cv2.drawContours(mask1, [biggestcontour], -1, 0, thickness=cv2.FILLED)\n", - " # # temp = cv2.drawContours(image, [biggestcontour], -1, 255, thickness=3)\n", - " # # imglist.append(temp)\n", - " \n", - " # mask1 = mf.padWithColour(mask1, sdim, sdim, fill=255)\n", - " \n", - " # mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel, iterations=1)\n", - " # mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, skernel)\n", - " # mask1 = mask1[sdim:-sdim, sdim:-sdim]\n", - " # imglist.append(mask1)\n", - " \n", - " # mask1merge = cv2.bitwise_and(mask1, mask1t)\n", - " # imglist.append(mask1merge)\n", - " \n", - " \n", - " \n", - " # maskc = cv2.cvtColor(mask1merge, cv2.COLOR_GRAY2BGR)\n", - " # # return maskc\n", - " # # return blurimage\n", - " # # print(blurimage)\n", - " # # print(maskc)\n", - " # whitedbackground = cv2.bitwise_or(image, maskc)\n", - " # imglist.append(whitedbackground)\n", - "\n", - " # return imglist\n", - " \n", - " \n", " imagecpy = image.copy()\n", " blurimage = cv2.blur(imagecpy, (13,13))\n", " \n", @@ -227,15 +203,18 @@ " # imagecpy = cv2.copyMakeBorder(blurimage, sdim, sdim, sdim, sdim, cv2.BORDER_REPLICATE)\n", " # return imagecpy\n", " # imagecpy = mf.padWithColour(image, hpadding=sdim, vpadding=sdim)\n", - " gray = cv2.cvtColor(blurimage, cv2.COLOR_BGR2GRAY)\n", + " \n", + " lab = cv2.cvtColor(image, cv2.COLOR_BGR2LAB)\n", + " gray = lab[:,:,0]\n", + " # gray = cv2.cvtColor(blurimage, cv2.COLOR_BGR2GRAY)\n", " \n", " # blur = cv2.blur(gray, (7,7))\n", " \n", " # window = 51\n", - " window = gray.shape[1]//15\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, 5)\n", + " thresh = cv2.adaptiveThreshold(gray, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY, window, 2)\n", " # thresh2 = cv2.threshold(gray, 0, 255, cv2.THRESH_OTSU)[1]\n", " # thresh = cv2.bitwise_and(thresh1, thresh2)\n", " # return thresh\n", @@ -257,7 +236,7 @@ " # dim = dotsize\n", " kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (dim, dim))\n", " morphedthresh = cv2.morphologyEx(thresh, cv2.MORPH_ERODE, kernel)\n", - " # return morphedthresh\n", + " return morphedthresh\n", " \n", " \n", " contours, heirarchy = cv2.findContours(morphedthresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)\n", @@ -273,8 +252,8 @@ " \n", " mask1 = mf.padWithColour(mask1, sdim, sdim, fill=0)\n", " \n", - " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel)\n", - " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, skernel)\n", + " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_CLOSE, skernel, iterations=1)\n", + " mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, skernel, iterations=1)\n", " # mask1 = cv2.morphologyEx(mask1, cv2.MORPH_OPEN, skernel)\n", " # return mask1\n", " \n", @@ -469,7 +448,7 @@ }, { "cell_type": "code", - "execution_count": 3039, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -489,13 +468,100 @@ }, { "cell_type": "code", - "execution_count": 3040, + "execution_count": 29, + "metadata": {}, + "outputs": [], + "source": [ + "def houghlinedeskewthencrop(baseimage, preppedimage, rotationangle, croprect):\n", + " # rotateddst1 = rotatewithexactpadding(preppedimage, rotationangle, fill=0)\n", + " # rotatedbaseimage = rotatewithexactpadding(baseimage, rotationangle, fill=(0,0,0))\n", + " # print(croprect)\n", + " hpad, vpad = mf.determineextrapadding(croprect[3], croprect[2], rotationangle)\n", + " # print(rotationangle)\n", + " # print(hpad, vpad)\n", + " adjustedrect = [croprect[0]-hpad, croprect[1]-vpad, croprect[2]+(2*hpad), croprect[3]+(2*vpad)]\n", + " adjustedrect = [int(s) for s in adjustedrect]\n", + " leftpad = -min(0, adjustedrect[0])\n", + " toppad = -min(0, adjustedrect[1])\n", + " rightpad = -min(0, baseimage.shape[1]-(adjustedrect[0]+adjustedrect[2]))\n", + " bottompad = -min(0, baseimage.shape[0]-(adjustedrect[1]+adjustedrect[3]))\n", + " \n", + " adjustedrect = [max(0, s) for s in adjustedrect]\n", + " \n", + " # print(leftpad, rightpad, toppad, bottompad)\n", + " ## DETERMINE PADDING AMOUNTS BECAUSE I THEN NEED TO PAD THE ORIGINAL IMAGE, CROP IT TO THE FIRST LEVEL, ROTATE, AND THEN CROP AGAIN\n", + " # print(adjustedrect)\n", + " # adjustedrect = croprect\n", + " borderType = cv2.BORDER_CONSTANT\n", + " padded = cv2.copyMakeBorder(baseimage, toppad, bottompad, leftpad, rightpad, borderType)\n", + " croppedpaddedimage = padded[adjustedrect[1]:adjustedrect[1]+adjustedrect[3], adjustedrect[0]:adjustedrect[0]+adjustedrect[2], :]\n", + " # print(croprect[2], croprect[3])\n", + " # print(croppedpaddedimage.shape)\n", + " # croppedog = baseimage[croprect[1]:croprect[1]+croprect[3], croprect[0]:croprect[0]+croprect[2], :]\n", + " # return croppedpaddedimage, croppedog\n", + " \n", + " rotatedbaseimage = mf.rotate(croppedpaddedimage, rotationangle)\n", + " \n", + " # print(vpad, hpad)\n", + " # print(croprect)\n", + " rotatedbaseimage = rotatedbaseimage[vpad:vpad+croprect[1]+croprect[3], hpad:hpad+croprect[0]+croprect[2], :]\n", + " # return rotatedbaseimage, 5\n", + " \n", + " \n", + " # print(preppedimage.shape)\n", + " rotateddst1 = mf.rotate(preppedimage, rotationangle)\n", + " # print(rotateddst1.shape)\n", + " # print(rotatedbaseimage.shape)\n", + " # return rotatedbaseimage, 5\n", + "\n", + " \n", + " sizemultiplier = rotatedbaseimage.shape[0]/rotateddst1.shape[0]\n", + " # print(sizemultiplier)\n", + " # return rotatedbaseimage, rotationangle\n", + "\n", + " croppedbaseimage = mf.houghlinepcrop(rotatedbaseimage, rotateddst1, sizemultiplier)\n", + "\n", + " finalbaseimage = mf.contourcrop(croppedbaseimage)\n", + "\n", + "\n", + " return finalbaseimage, rotationangle" + ] + }, + { + "cell_type": "code", + "execution_count": 30, + "metadata": {}, + "outputs": [], + "source": [ + "def houghlinedeskewandcrop(image):\n", + " canny, ogimage, rect = mf.prepimageforhoughline(image, returnrect=True) ## scaling and cropping occurs. need to also return the changes done\n", + " # return canny, croppedogimage\n", + " # print(canny.shape)\n", + " # print(croppedogimage.shape)\n", + "\n", + " ## -----------------finding angle to deskew-----------------\n", + " rotationangle = mf.houghlinedeskewangle(canny)\n", + " # print(rotationangle)\n", + "\n", + " \n", + " # rotatorrect = findcroprectforangle(rect, angle)\n", + "\n", + " # -----------------end of finding angle to deskew-----------------\n", + "\n", + " ## -----------------deskewing and then cropping-----------------\n", + " outimg, angle = houghlinedeskewthencrop(ogimage, canny, rotationangle, rect)\n", + " return outimg, angle" + ] + }, + { + "cell_type": "code", + "execution_count": 31, "metadata": {}, "outputs": [], "source": [ "def houghlineprocessing(image):\n", - " croppedanddeskewed, angle = mf.houghlinedeskewandcrop(image)\n", - " # return croppedanddeskewed\n", + " croppedanddeskewed, angle = houghlinedeskewandcrop(image)\n", + " return croppedanddeskewed\n", " \n", " \n", " postprocessed = cropclarifying(croppedanddeskewed)\n", @@ -520,7 +586,16 @@ }, { "cell_type": "code", - "execution_count": 3041, + "execution_count": 32, + "metadata": {}, + "outputs": [], + "source": [ + "# print(img.shape)" + ] + }, + { + "cell_type": "code", + "execution_count": 33, "metadata": {}, "outputs": [], "source": [ @@ -535,7 +610,7 @@ }, { "cell_type": "code", - "execution_count": 3042, + "execution_count": 34, "metadata": {}, "outputs": [], "source": [ @@ -549,7 +624,7 @@ }, { "cell_type": "code", - "execution_count": 3043, + "execution_count": 35, "metadata": {}, "outputs": [], "source": [ @@ -561,7 +636,7 @@ }, { "cell_type": "code", - "execution_count": 3044, + "execution_count": 36, "metadata": {}, "outputs": [], "source": [ @@ -570,7 +645,7 @@ }, { "cell_type": "code", - "execution_count": 3045, + "execution_count": 37, "metadata": {}, "outputs": [], "source": [ @@ -580,7 +655,7 @@ }, { "cell_type": "code", - "execution_count": 3046, + "execution_count": 38, "metadata": {}, "outputs": [], "source": [ @@ -610,14 +685,14 @@ }, { "cell_type": "code", - "execution_count": 3047, + "execution_count": 39, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "average time: 8.021544203162193(s)\n" + "average time: 0.1456429362297058(s)\n" ] } ], @@ -628,7 +703,7 @@ }, { "cell_type": "code", - "execution_count": 3048, + "execution_count": 40, "metadata": {}, "outputs": [], "source": [ @@ -638,7 +713,7 @@ }, { "cell_type": "code", - "execution_count": 3049, + "execution_count": 41, "metadata": {}, "outputs": [], "source": [ @@ -647,7 +722,7 @@ }, { "cell_type": "code", - "execution_count": 3050, + "execution_count": 42, "metadata": {}, "outputs": [], "source": [ diff --git a/code/autocropper/myfunctions.py b/code/autocropper/myfunctions.py index 8dd24af..ac55487 100644 --- a/code/autocropper/myfunctions.py +++ b/code/autocropper/myfunctions.py @@ -91,10 +91,6 @@ 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 @@ -346,7 +342,7 @@ def rotateLine(img, line, angle, returnint=True): pt2 = rotatePoint(img, (line[2],line[3]), angle, returnint) return (pt1[0], pt1[1], pt2[0], pt2[1]) -def prepimageforhoughline(image): +def prepimageforhoughline(image, returnrect=True): prepped, scaler, hp, vp = squareandthenresize(image, fill=255, width=1000, returnscalerinfo=True) prepped, croprect = premorphCrop(prepped) if (prepped.shape[1] > prepped.shape[0]): @@ -368,9 +364,12 @@ 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) - return dst1, accompaniedimage + if returnrect: + return dst1, image, finalcroprect + else: + accompaniedimage = image[finalcroprect[1]:finalcroprect[1]+finalcroprect[3], finalcroprect[0]:finalcroprect[0]+finalcroprect[2], :] + # accompaniedimage = squarepad(accompaniedimage, fill=255) + return dst1, accompaniedimage def houghlinedeskewangle(image): lines = cv2.HoughLines(image, 1, np.pi/180, int(max(image.shape[0], image.shape[1])/6), None, 0, 0) @@ -399,8 +398,7 @@ def houghlinedeskewangle(image): rotationangle = np.rad2deg(mode) return rotationangle -def determineextrapadding(img, angle): - h, w = img.shape[0], img.shape[1] +def determineextrapadding(h,w, angle): radangle = abs(np.deg2rad(angle)) # print(radangle) totalheightrot = w*np.sin(radangle) + h*np.cos(radangle) @@ -413,7 +411,8 @@ def determineextrapadding(img, angle): return hpad, vpad def rotatewithexactpadding(img, angle, fill=(0,0,0)): - hpad, vpad = determineextrapadding(img, angle) + h, w = img[0], img[1] + hpad, vpad = determineextrapadding(w,h, angle) baseimage = padWithColour(img, hpad, vpad, fill=fill) rotatedimg = rotate(baseimage, angle) return rotatedimg @@ -477,8 +476,21 @@ def contourcrop(baseimage): return finalbaseimage def houghlinedeskewthencrop(baseimage, preppedimage, rotationangle): - rotateddst1 = rotatewithexactpadding(preppedimage, rotationangle, fill=0) - rotatedbaseimage = rotatewithexactpadding(baseimage, rotationangle, fill=(0,0,0)) + # rotateddst1 = rotatewithexactpadding(preppedimage, rotationangle, fill=0) + # rotatedbaseimage = rotatewithexactpadding(baseimage, rotationangle, fill=(0,0,0)) + hpad, vpad = mf.determineextrapadding(rect[3], rect[2], rotationangle) + adjustedrect = [rect[0]-hpad, rect[1]-vpad, rect[2]+(2*hpad), rect[3]+(2*vpad)] + croppedogimage = croppedogimage[adjustedrect[1]:adjustedrect[1]+adjustedrect[3], adjustedrect[0]:adjustedrect[0]+adjustedrect[2], :] + + houghlinerotate() + + + + print(preppedimage.shape) + rotateddst1 = rotate(preppedimage, rotationangle) + print(rotateddst1.shape) + rotatedbaseimage = rotate(baseimage, rotationangle) + sizemultiplier = rotatedbaseimage.shape[0]/rotateddst1.shape[0] # print(sizemultiplier) # return rotatedbaseimage, rotationangle