%PDF- %PDF-
Direktori : /usr/share/hplip/base/ |
Current File : //usr/share/hplip/base/imageprocessing.py |
#!/usr/bin/env python # -*- coding: utf-8 -*- # # (c) Copyright 2003-2018 HP Development Company, L.P. # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # # Author: Santhosh M, Ram Varma P, Srinivas Teja, Badal Kumar Gouda # #from PIL import ImageStat from base import utils, os_utils from base.g import * #from PIL import Image #from PIL import ImageEnhance #from tesserocr import PyTessBaseAPI, PSM #from PyPDF2 import PdfFileMerger #from PyPDF2 import PdfFileReader #import numpy as np #import PyPDF2 #import subprocess #import imutils #import cv2 import math import os import sys import platform import re import subprocess from installer import core_install from installer import dcheck #from .dcheck import * threshold = 200 #the average of the darkest values must be _below_ this to count (0 is darkest, 255 is lightest) obviousness = 50 #how many of the darkest pixels to include (1 would mean a single dark pixel triggers it) punchhole_margin = 190 #the margin considered for the detection of punch hole from the edge of the paper for punch hole removal feature def rotate_image(image, angle): import numpy as np import cv2 """ Rotates an OpenCV 2 / NumPy image about it's centre by the given angle (in radians). The returned image will be large enough to hold the entire new image, with a black background """ # Get the image size # No that's not an error - NumPy stores image matricies backwards image_size = (image.shape[1], image.shape[0]) image_center = tuple(np.array(image_size) / 2) # Convert the OpenCV 3x2 rotation matrix to 3x3 rot_mat = np.vstack( [cv2.getRotationMatrix2D(image_center, angle, 1.0), [0, 0, 1]] ) rot_mat_notranslate = np.matrix(rot_mat[0:2, 0:2]) # Shorthand for below calcs image_w2 = image_size[0] * 0.5 image_h2 = image_size[1] * 0.5 # Obtain the rotated coordinates of the image corners rotated_coords = [ (np.array([-image_w2, image_h2]) * rot_mat_notranslate).A[0], (np.array([ image_w2, image_h2]) * rot_mat_notranslate).A[0], (np.array([-image_w2, -image_h2]) * rot_mat_notranslate).A[0], (np.array([ image_w2, -image_h2]) * rot_mat_notranslate).A[0] ] # Find the size of the new image x_coords = [pt[0] for pt in rotated_coords] x_pos = [x for x in x_coords if x > 0] x_neg = [x for x in x_coords if x < 0] y_coords = [pt[1] for pt in rotated_coords] y_pos = [y for y in y_coords if y > 0] y_neg = [y for y in y_coords if y < 0] right_bound = max(x_pos) left_bound = min(x_neg) top_bound = max(y_pos) bot_bound = min(y_neg) new_w = int(abs(right_bound - left_bound)) new_h = int(abs(top_bound - bot_bound)) # We require a translation matrix to keep the image centred trans_mat = np.matrix([ [1, 0, int(new_w * 0.5 - image_w2)], [0, 1, int(new_h * 0.5 - image_h2)], [0, 0, 1] ]) # Compute the tranform for the combined rotation and translation affine_mat = (np.matrix(trans_mat) * np.matrix(rot_mat))[0:2, :] # Apply the transform result = cv2.warpAffine( image, affine_mat, (new_w, new_h), flags=cv2.INTER_LINEAR ) return result def largest_rotated_rect(w, h, angle): """ Given a rectangle of size wxh that has been rotated by 'angle' (in radians), computes the width and height of the largest possible axis-aligned rectangle within the rotated rectangle. Original JS code by 'Andri' and Magnus Hoff from Stack Overflow Converted to Python by Aaron Snoswell """ quadrant = int(math.floor(angle / (math.pi / 2))) & 3 sign_alpha = angle if ((quadrant & 1) == 0) else math.pi - angle alpha = (sign_alpha % math.pi + math.pi) % math.pi bb_w = w * math.cos(alpha) + h * math.sin(alpha) bb_h = w * math.sin(alpha) + h * math.cos(alpha) gamma = math.atan2(bb_w, bb_w) if (w < h) else math.atan2(bb_w, bb_w) delta = math.pi - alpha - gamma length = h if (w < h) else w d = length * math.cos(alpha) a = d * math.sin(alpha) / math.sin(delta) y = a * math.cos(gamma) x = y * math.tan(gamma) return ( bb_w - 2 * x, bb_h - 2 * y ) def crop_around_center(image, width, height): """ Given a NumPy / OpenCV 2 image, crops it to the given width and height, around it's centre point """ image_size = (image.shape[1], image.shape[0]) image_center = (int(image_size[0] * 0.5), int(image_size[1] * 0.5)) if(width > image_size[0]): width = image_size[0] if(height > image_size[1]): height = image_size[1] x1 = int(image_center[0] - width * 0.5) x2 = int(image_center[0] + width * 0.5) y1 = int(image_center[1] - height * 0.5) y2 = int(image_center[1] + height * 0.5) return image[y1:y2, x1:x2] def Deskew_angle1(img): import numpy as np import cv2 from PIL import Image import math image=np.array(img) image_height, image_width = image.shape[0:2] gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) edges = cv2.Canny(gray, 100, 100, apertureSize=3) lines = cv2.HoughLinesP(edges, 1, math.pi / 180.0, 100, minLineLength=100, maxLineGap=5) angles = [] temp_angles = [] for x1, y1, x2, y2 in lines[0]: angle = math.degrees(math.atan2(y2 - y1, x2 - x1)) temp_angles.append(angle) angle = abs(angle) if angle != 0: angles.append(angle) if not angles: median_angle = 0 return median_angle else: median_angle = min(angles) for item in temp_angles: if median_angle == abs(item): median_angle = item if (median_angle >= 15 or median_angle <= -15): median_angle = 0 return median_angle def Deskew_angle2(img): import sys import math #import matplotlib.pyplot as plt import numpy as np from PIL import Image as im from scipy.ndimage import interpolation as inter #input_file = sys.argv[1] #img = im.open("hpscan004.png") # convert to binary wd, ht = img.size pix = np.array(img.convert('1').getdata(), np.uint8) bin_img = 1 - (pix.reshape((ht, wd)) / 255.0) #plt.imshow(bin_img, cmap='gray') #plt.savefig('binary.png') def find_score(arr, angle): data = inter.rotate(arr, angle, reshape=False, order=0) hist = np.sum(data, axis=1) score = np.sum((hist[1:] - hist[:-1]) ** 2) return hist, score delta = 1 limit = 5 angles = np.arange(-limit, limit+delta, delta) scores = [] for angle in angles: hist, score = find_score(bin_img, angle) scores.append(score) if not scores: best_angle = 0 return best_angle else: best_score = max(scores) best_angle = angles[scores.index(best_score)] if best_angle < 0 : best_angle = best_angle else: best_angle = best_angle if (best_angle >= 15 or best_angle <= -15): best_angle = 0 return best_angle def deskew(im): import numpy as np import cv2 from PIL import Image import math angle1 = Deskew_angle1(im) angle2 = Deskew_angle2(im) #angle = max([Deskew_angle1(img),Deskew_angle2(img)]) if angle1 <= 0 and angle2 <= 0: angle = min([angle1,angle2]) else: angle = max([angle1,angle2]) if not (angle != 90 and angle != -90): return im if (angle >= 15 or angle <= -15): return im image = np.array(im) image_height, image_width = image.shape[0:2] image_orig = np.copy(image) image_rotated = rotate_image(image, angle) image_rotated_cropped = crop_around_center( image_rotated, *largest_rotated_rect( image_width, image_height, math.radians(angle) ) ) return Image.fromarray(image_rotated_cropped) def blankpage(im,lineart_mode): from PIL import ImageStat ''' check for the blank page ''' v = ImageStat.Stat(im).var #print(v) if lineart_mode and ( v[0] < 300 ): return True if ( ( v[0] < 300 ) and ( v[1] < 300 ) and ( v[2] < 300)) and (lineart_mode ==False): return True else: return False def rotate_bound(image, angle): import cv2 import numpy as np # grab the dimensions of the image and then determine the # center (h, w) = image.shape[:2] (cX, cY) = (w / 2, h / 2) # grab the rotation matrix (applying the negative of the # angle to rotate clockwise), then grab the sine and cosine # (i.e., the rotation components of the matrix) M = cv2.getRotationMatrix2D((cX, cY), -angle, 1.0) cos = np.abs(M[0, 0]) sin = np.abs(M[0, 1]) # compute the new bounding dimensions of the image nW = int((h * sin) + (w * cos)) nH = int((h * cos) + (w * sin)) # adjust the rotation matrix to take into account translation M[0, 2] += (nW / 2) - cX M[1, 2] += (nH / 2) - cY # perform the actual rotation and return the image return cv2.warpAffine(image, M, (nW, nH)) def orientangle(im): if int(get_tesseract_version()) >= 4: import locale locale.setlocale(locale.LC_ALL, 'C') from tesserocr import PyTessBaseAPI, PSM else: from tesserocr import PyTessBaseAPI, PSM with PyTessBaseAPI(psm=PSM.AUTO_OSD) as api: try: api.SetImage(im) except IOError: im = im.convert("RGB") api.SetImage(im) api.Recognize() it = api.AnalyseLayout() orientation, direction, order, deskew_angle = it.Orientation() return orientation def autoorient(im, angle): from PIL import Image import numpy as np #import imutils orient_dict ={ 0 :0 ,1:270, 2:180, 3:90} rotated=rotate_bound(np.array(im),orient_dict[angle]) return Image.fromarray(rotated) #Auto Crop Code def initialcrop(img): w, h = img.size return img.crop((20, 20, w-20, h-20)) def find_line(vals): #implement edge detection once, use many times for i,tmp in enumerate(vals): tmp.sort() average = float(sum(tmp[:obviousness]))/len(tmp[:obviousness]) if average <= threshold: return i return i #i is left over from failed threshold finding, it is the bounds def getbox(img): import numpy as np #get the bounding box of the interesting part of a PIL image object #this is done by getting the darekest of the R, G or B value of each pixel #and finding were the edge gest dark/colored enough #returns a tuple of (left,upper,right,lower) width, height = img.size #for making a 2d array retval = [0,0,width,height] #values will be disposed of, but this is a black image's box pixels = list(img.getdata()) vals = [] #store the value of the darkest color for pixel in pixels: vals.append(min(pixel)) #the darkest of the R,G or B values #make 2d array pyPlatform = platform.python_version() num = pyPlatform.split('.') if num[0] >= '3': vals = np.array([vals[i * width:(i + 1) * width] for i in range(height)]) else: vals = np.array([vals[i * width:(i + 1) * width] for i in xrange(height)]) #start with upper bounds forupper = vals.copy() retval[1] = find_line(forupper) #next, do lower bounds #forlower = vals.copy() forlower = np.flipud(forupper) retval[3] = height - find_line(forlower) #left edge, same as before but roatate the data so left edge is top edge #forleft = vals.copy() forleft = np.swapaxes(forupper,0,1) retval[0] = find_line(forleft) #and right edge is bottom edge of rotated array #forright = vals.copy() forright = np.swapaxes(forupper,0,1) forright = np.flipud(forright) retval[2] = width - find_line(forright) if retval[0] >= retval[2] or retval[1] >= retval[3]: return None return tuple(retval) def autocrop(im): from PIL import Image import numpy as np import cv2 blurred = cv2.blur(np.array(im), (3,3)) canny = auto_canny(blurred) ## find the non-zero min-max coords of canny pts = np.argwhere(canny>0) y1,x1 = pts.min(axis=0) y2,x2 = pts.max(axis=0) ## crop the region cropped = np.array(im)[y1:y2, x1:x2] img = initialcrop(Image.fromarray(cropped)) box = getbox(img) result = img.crop(box) return result def mixedfeed(im): from PIL import Image import numpy as np import cv2 blurred = cv2.blur(np.array(im), (3,3)) canny = cv2.Canny(blurred, 10, 200) ## find the non-zero min-max coords of canny pts = np.argwhere(canny>0) y1,x1 = pts.min(axis=0) y2,x2 = pts.max(axis=0) ## crop the region cropped = np.array(im)[0:y2, x1:x2] return Image.fromarray(cropped) def generatePdfFile(adf_page_files,outputfile): try: from PyPDF2 import PdfFileMerger, PdfFileReader merger = PdfFileMerger() except: from PyPDF2 import PdfMerger as PdfFileMerger from PyPDF2 import PdfReader as PdfFileReader merger = PdfFileMerger() #temp = utils.createSequencedFilename("hpscanAuto1", ".pdf") #temp = 'temp.pdf' #output_file1 = utils.createSequencedFilename("hpscanmultifeed", ".pdf") for p in adf_page_files: '''image = Image.open(p) image = image.convert("RGB") image.save(temp) merger.append(open(temp,'rb')) cmd = 'rm -f ' + temp utils.run(cmd)''' merger.append(PdfFileReader(p), 'hpscan') '''with open(outputfile, 'wb') as fout: merger.write(fout)''' merger.write(outputfile) for p in adf_page_files: os.remove(p) return outputfile def generatePdfFile_canvas(adf_page_files,outputfile,orient_list,brx,bry,tlx,tly,output_path): #print ("called canvas") from reportlab.pdfgen import canvas from PIL import Image '''adf_page_files2 = [] for p in adf_page_files: output = utils.createSequencedFilename("hpscan", ".png", output_path) cmd = "convert %s %s" %(p,output) status = utils.run(cmd) #print (status[0]) #print (status[1]) if status[0] == -1: #print ("entered status -1") log.error("Convert command not found.") sys.exit(6) adf_page_files2.append(output) #print(adf_page_files2) for p in adf_page_files: os.unlink(p) adf_page_files = adf_page_files2 #print (adf_page_files) #print (adf_page_files2) #print (outputfile)''' c = canvas.Canvas(outputfile, (brx/0.3528, bry/0.3528)) i=0 for p in adf_page_files: #log.info("Processing page %s..." % p) im = Image.open(p) try: if orient_list and (orient_list[i] == 1 or orient_list[i] == 3): c.setPageSize(((bry-tly)/0.3528, (brx-tlx)/0.3528)) c.drawInlineImage(im, (tlx/0.3528), (tly/0.3528), ((bry-tly)/0.3528), ((brx-tlx)/0.3528)) else: c.setPageSize(((brx-tlx)/0.3528, (bry-tly)/0.3528)) c.drawInlineImage(im, (tlx/0.3528), (tly/0.3528), ((brx-tlx)/0.3528),((bry-tly)/0.3528)) except NameError: #log.error("A problem has occurred with PDF generation. This is a known bug in ReportLab. Please update your install of ReportLab to version 2.0 or greater.") sys.exit(1) except AssertionError as e: log.error(e) if PY3: #log.note("You might be running an older version of reportlab. Please update to the latest version") #log.note("More information is available at http://hplipopensource.com/node/369") sys.exit(1) except Exception as e: #log.error(e) #log.note("Try Updating to reportlab version >= 3.2") sys.exit(1) c.showPage() os.unlink(p) i+=1 #log.info("Saving to file %s" % outputfile) c.save() #del adf_page_files2[:] #del adf_page_files[:] return outputfile '''log.info("Viewing PDF file in %s" % pdf_viewer) cmd = "%s %s &" % (pdf_viewer, output) os_utils.execute(cmd) sys.exit(0)''' def documentmerge(adf_page_files,ext,output_path): import numpy as np from PIL import Image try: from PyPDF2 import PdfFileMerger if ext == ".pdf": merger = PdfFileMerger() except: from PyPDF2 import PdfMerger as PdfFileMerger if ext == ".pdf": merger = PdfFileMerger() #print(output_type) #adf_page_files2 = [] list_im = [] i = 0 '''if ext == ".pdf": merger = PdfFileMerger() for p in adf_page_files: output = utils.createSequencedFilename("hpscan", ".png", output_path) cmd = "convert %s %s" %(p,output) status = utils.run(cmd) #print (status[0]) #print (status[1]) if status[0] == -1: #print ("entered status -1") log.error("Convert command not found.") sys.exit(6) adf_page_files2.append(output) #print(adf_page_files2) for p in adf_page_files: os.unlink(p) adf_page_files = adf_page_files2 #del adf_page_files2[:] #print(adf_page_files)''' while i < len(adf_page_files): list_im = [adf_page_files[i], adf_page_files[i+1]] imgs = [Image.open(y) for y in list_im ] # pick the image which is the smallest, and resize the others to match it (can be arbitrary image shape here) min_shape = sorted( [(np.sum(z.size), z.size ) for z in imgs])[0][1] imgs_comb = np.hstack( (np.asarray( w.resize(min_shape) ) for w in imgs ) ) # save that beautiful picture imgs_comb = Image.fromarray( imgs_comb) for p in list_im: os.remove(p) '''if ext == ".pdf": temp = 'temp.pdf' imgs_comb = imgs_comb.convert("RGB") imgs_comb.save( temp ) merger.append(open(temp,'rb')) cmd = 'rm -f ' + temp utils.run(cmd) else:''' if ext == ".pdf": temp = 'temp.pdf' imgs_comb = imgs_comb.convert("RGB") imgs_comb.save( temp ) merger.append(open(temp,'rb')) cmd = 'rm -f ' + temp utils.run(cmd) #adf_page_files2.append(temp) #merger = PdfFileMerger() else: temp = utils.createSequencedFilename("hpscandoc", ext, output_path) imgs_comb.save( temp ) i = i + 2 if ext == ".pdf": output = utils.createSequencedFilename("hpscandoc", ext, output_path) with open(output, 'wb') as fout: merger.write(fout) '''del adf_page_files2[:] del adf_page_files[:]''' return output else: return None def auto_canny(image, sigma = 0.33): import numpy as np import cv2 # compute the mediam of the single channel pixel intensities v = np.median(image) # apply automatic Canny edge detection using the computed median lower = int(max(0, (1.0 - sigma) * v)) upper = int(min(255, (1.0 + sigma) *v)) edged = cv2.Canny(image, lower, upper) # return edged image return edged def crushed(im): from PIL import Image import numpy as np #gray = im.convert('L') bw = np.asarray(im).copy() bw[bw < 90] = 0 # Black bw[bw >= 180] = 255 # White return Image.fromarray(bw) #imfile.save("result_bw.png") #return imfile def bg_color_removal(im): import cv2 import numpy as np from PIL import Image #im.save("Sample.png") image = np.array(im) #print (image) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) alpha = 2.5 beta = -0.0 denoised = alpha * gray + beta denoised = np.clip(denoised, 0, 255).astype(np.uint8) denoised = cv2.fastNlMeansDenoising(denoised, None, 31, 7, 21) return Image.fromarray(denoised) def adjust_sharpness(im, factor): from PIL import ImageEnhance #image = Image.open(input_image) enhancer_object = ImageEnhance.Sharpness(im) out = enhancer_object.enhance(factor) return out def adjust_contrast(im, factor): from PIL import ImageEnhance #image = Image.open(input_image) enhancer_object = ImageEnhance.Contrast(im) out = enhancer_object.enhance(factor) return out def adjust_brightness(im, factor): from PIL import ImageEnhance #image = Image.open(input_image) enhancer_object = ImageEnhance.Brightness(im) out = enhancer_object.enhance(factor) return out def adjust_color(im, factor): from PIL import ImageEnhance #image = Image.open(input_image) enhancer_object = ImageEnhance.Color(im) out = enhancer_object.enhance(factor) return out def merge_PDF_viewer(output,ocr): if (output.endswith('.pdf') == False): print("PDF viewer is trying open other than PDF file") return pdf_viewer = '' pdf_viewer_list = ['kpdf', 'acroread', 'xpdf', 'evince', 'xdg-open'] for v in pdf_viewer_list: vv = utils.which(v) if vv: pdf_viewer = os.path.join(vv, v) break if ocr == True: #g = output.split(".pdf") #output_ocr = g[0] +"_ocr.pdf" #do not create ocr file based on the output file name, # create unique sequenced file for OCR # because original output file should be deleted if OCR was successful output_ocr = utils.createSequencedFilename("hpscan_ocr_", ".pdf") if sys.version_info[0] == 3: out = subprocess.Popen(['ocrmypdf',output,output_ocr],stdout=subprocess.PIPE,stderr=subprocess.STDOUT) stdout,stderr =out.communicate() else: out = subprocess.Popen(['pypdfocr',output],stdout=subprocess.PIPE,stderr=subprocess.STDOUT) stdout,stderr =out.communicate() if os.path.isfile(output_ocr): log.debug("OCR was successful") cmd = pdf_viewer + " " + output_ocr + " " + "&" #OCR was success so delete the non-ocr original output os.unlink(output) else: log.debug("OCR failed to generate, returning original file") cmd = pdf_viewer + " " + output + " " + "&" os_utils.execute(cmd) else: log.debug("OCR was not called, returning original file") cmd = pdf_viewer + " " + output + " " + "&" os_utils.execute(cmd) def check_pil(): scanjet_flag = None try: import PIL except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except: scanjet_flag=str("Error occurred") return scanjet_flag def check_numpy(): scanjet_flag = None try: import numpy as np except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except: scanjet_flag=str("Error occurred") return scanjet_flag def check_opencv(): scanjet_flag = None try: import cv2 except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except: scanjet_flag=str("Error occurred") return scanjet_flag def check_pypdfocr(): scanjet_flag = None try: import pypdfocr except: try: import ocrmypdf except: scanjet_flag=str("Error occurred") return scanjet_flag def check_skimage(): scanjet_flag = None try: import skimage except ImportError as error: scanjet_flag=str(error) except: scanjet_flag=str("Error occurred") return scanjet_flag def check_tesserocr_imutils(): scanjet_flag = None try: if int(get_tesseract_version()) >= 4: import locale locale.setlocale(locale.LC_ALL, 'C') import tesserocr else: import tesserocr except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except AttributeError as error: scanjet_flag=str(error) except: scanjet_flag=str("Error occurred") return scanjet_flag def check_pypdf2(): scanjet_flag = None try: import PyPDF2 except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except: scanjet_flag=str("Error occurred") return scanjet_flag def check_zbar(): scanjet_flag = None pyPlatform = platform.python_version() num = pyPlatform.split('.') if num[0] < '3': try: import zbar except ImportError as error: scanjet_flag=str(error) #.split(' ')[-1] except: scanjet_flag=str("Error occurred") return scanjet_flag else: return 'zbar' def dominantcolor(xcord, ycord, radius, img): import numpy as np from skimage import io l = [] d = {} width, height, channels = img.shape x1 = punchhole_margin x2 = (int)(width - punchhole_margin) y1 = (int)(height - punchhole_margin) y2 = punchhole_margin if((0 < ycord < width) and (0 < xcord < y2)): s1 = (xcord -4) s2 = (xcord +4) s3 = (ycord + (radius)) s4 = (ycord + (8+radius)) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) s1 = (xcord -4) s2 = (xcord +4) s3 = (ycord - (radius)) s4 = (ycord - (8+radius)) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) if((0 < ycord < width) and (y1 < xcord < height)): s1 = (xcord -4) s2 = (xcord +4) s3 = (ycord + (radius)) s4 = (ycord + (8+radius)) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) s1 = (xcord -4) s2 = (xcord +4) s3 = (ycord - (radius)) s4 = (ycord - (8+radius)) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) if((x2 < ycord < width) and (0 < xcord < height)): s1 = (xcord - (8+radius)) s2 = (xcord - (radius)) s3 = (ycord - 4) s4 = (ycord + 4) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) s1 = (xcord + (8+radius)) s2 = (xcord + (radius)) s3 = (ycord - 4) s4 = (ycord + 4) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) if((0 < ycord < x1) and (0 < xcord < height)): s1 = (xcord - (8+radius)) s2 = (xcord - (radius)) s3 = (ycord - 4) s4 = (ycord + 4) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) s1 = (xcord + (8+radius)) s2 = (xcord + (radius)) s3 = (ycord - 4) s4 = (ycord + 4) myimg = img[s3:s4, s1:s2] w , h, c = myimg.shape for i in range(0, w-1): for j in range(0, h-1): rgblist = myimg[i,j] l.append((rgblist[0],rgblist[1],rgblist[2])) m = set(l) for z in m: d[l.count(z)] = z d_keys = d.keys() z_list = list(d_keys) sortlist = sorted(z_list) t = (d[sortlist[-1]]) return list(t) def lineargradient(dominant_color, white_color, pixelcount): n=pixelcount s = tuple(dominant_color) f = tuple(white_color) RGB_list = [s] # Calcuate a color at each evenly spaced value of t from 1 to n for t in range(1, n): # Interpolate RGB vector for color at the current value of t curr_vector = [int(s[j] + (float(t)/(n-1))*(f[j]-s[j])) for j in range(3)] # Add it to our list of output colors RGB_list.append(curr_vector) return RGB_list def punchhole_removal(im): import numpy as np from PIL import Image from skimage import io from skimage.color import rgba2rgb, rgb2gray from skimage.transform import hough_circle, hough_circle_peaks from skimage.feature import canny try: from skimage.draw import circle # py2 legacy code draw_imported = "circle" except ImportError: from skimage.draw import disk #circle module renamed disk ref:HPLIP-1475 draw_imported = "disk" from skimage.util import img_as_ubyte ''' check for punch holes and remove ''' max_peaks = 24 #maximum number of peaks to be found. changed from 99 to 24 for reducing the unnecessary punch holes being filled. img = np.array(im) # Load picture . if( img.shape[-1] == 3): # check for 3 channel rgb data img_gray = rgb2gray(img) # convert to gray else: # it is 4 channel rgba data img_gray = rgb2gray(rgba2rgb(img)) # first convert to rgb, then convert to gray ref:HPLIP-1475 image = img_as_ubyte(img_gray) width, height = image.shape x1 = punchhole_margin x2 = (int)(width - punchhole_margin) y1 = (int)(height - punchhole_margin) y2 = punchhole_margin edges = auto_canny(image) #edges = canny(image, 3, 10, 40) # perform canny to detect the edges hough_radii = np.arange(31, 34, 1) #get the radius range with step as 1. hough_res = hough_circle(edges, hough_radii) # detect the circles centres coordinates # Select the most prominent circles based on the max_peaks accums, cx, cy, radii = hough_circle_peaks(hough_res, hough_radii,total_num_peaks=max_peaks) for center_y, center_x, radius in zip(cy, cx, radii): #if the circles centres fall in the border regions, #get the dominant color near the hole and fill the hole with a linear gradient of the dominant color if(((0 < center_y < width) and (0 < center_x < y2)) or \ ((0 < center_y < width) and (y1 < center_x < height)) or\ ((0 < center_y < x1) and (0 < center_x < height)) or \ ((x2 < center_y < width) and (0 < center_x < height))): if(draw_imported == "circle"): rr, cc= circle(center_y, center_x, radius+1, img.shape) #py2 legacy code elif(draw_imported == "disk"): rr, cc= disk((center_y, center_x), radius+1, shape=img.shape) dominantpix = dominantcolor(center_x, center_y, radius,img) for i , j in zip(list(rr), list(cc)): img[i,j]= (dominantpix[0], dominantpix[1], dominantpix[2], 255) finalimage=Image.fromarray(img) return finalimage def color_dropout(im,color,color_range): from PIL import Image import numpy as np import cv2 import math import sys #print(color, color_range) npimg = np.array(im,dtype="uint8") hsv_img = cv2.cvtColor(npimg, cv2.COLOR_RGB2HSV) hsv_color = list(rgb2hsv(color[0], color[1], color[2])) boundaries = [] boundaries.append(([max(hsv_color[0] - 10, 0), max(hsv_color[1] - color_range, 0), max(hsv_color[2] - color_range, 0)], [min(hsv_color[0] + 10, 179), min(hsv_color[1] + color_range, 255), min(hsv_color[2] + color_range, 255)])) for (lower, upper) in boundaries: lower = np.array(lower,dtype="uint8") upper = np.array(upper,dtype="uint8") #print(lower, upper) mask = cv2.inRange(hsv_img, lower, upper) height, width = mask.shape for h in range (0,height-1): for w in range (0,width-1): if (mask[h,w] == 255): npimg[h,w] = (255,255,255,255) finalimage = Image.fromarray(npimg) return finalimage # Crop out edges from the scan area:", "--edge_erase_value=<border crop value in pixel> # where <edge_erase_value> is number of pixels to be removed from corners # <im> is PIL image type def edge_erase(im,edge_erase_value): log.debug("edge_erase called with value=%d px" %edge_erase_value) # Importing ImageOps class from PIL module from PIL import ImageOps width, height= im.size left = edge_erase_value top = edge_erase_value right = height-edge_erase_value bottom = width-edge_erase_value # Cropped image of above dimension # (It will not change original image) im1 = im.crop((left, top, bottom, right)) #fill the cropped part with white color #to do - implement fill color based on user input im = ImageOps.expand(im1,border=edge_erase_value,fill='white') return im def rgb2hsv(r, g, b): r, g, b = r/255.0, g/255.0, b/255.0 mx = max(r, g, b) mn = min(r, g, b) df = mx-mn if mx == mn: h = 0 elif mx == r: h = (60 * ((g-b)/df) + 360) % 360 elif mx == g: h = (60 * ((b-r)/df) + 120) % 360 elif mx == b: h = (60 * ((r-g)/df) + 240) % 360 if mx == 0: s = 0 else: s = df/mx v = mx s = int(s * 255) v = int(v * 255) h = int(h/2) return h, s, v def check_scipy(): scanjet_flag = None try: from scipy.ndimage import interpolation as inter except ImportError as error: scanjet_flag=str(error) except: scanjet_flag=str("Error occurred") return scanjet_flag def _read_string(s): if sys.version_info >= (3, 0): return s.decode('UTF-8') else: return s def get_tesseract_version(): try: p = subprocess.Popen(['tesseract', '-v'], stderr=subprocess.PIPE, stdout=subprocess.PIPE) stdout_version, version = p.communicate() version = _read_string(version).strip() if version == '': version = _read_string(stdout_version).strip() version_match = re.search(r'^tesseract ((?:\d+\.)+\d+).*', version, re.M) if version_match: version = version_match.group(1) return version[0] else: return 0 except OSError as e: #log.debug('Failed to extract tesseract version from executable: {}'.format(e)) return 0