def rgb_to_sketch(pic_name): #img_rgb = cv2.imread(args["image"]) img_rgb = cv2.imread(pic_name) #print(img_rgb.shape) img_gray = cv2.cvtColor(img_rgb, cv2.COLOR_BGR2GRAY) ##转为灰度图 ##可改变图片的尺寸,只设置h或者只设置w就会按照等比例放大或缩小;若都指定,则按照指定的大小变换 img_gray = myutils.resize(img_gray, height=500) img_blur = cv2.GaussianBlur(img_gray, ksize=(21, 21), sigmaX=0, sigmaY=0) ##高斯滤波 ##可改变scale的值来改变生成效果,scale越小,会让一些原本比较亮的区域变得更加清晰 img_blend = cv2.divide(img_gray, img_blur, scale=225) ##图像相除实现素描效果 return img_blend
# 计算外接矩形并且resize成合适大小 (x, y, w, h) = cv2.boundingRect(c) roi = ref[y:y + h, x:x + w] roi = cv2.resize(roi, (57, 88)) #调整矩形框的大小 # 每一个数字对应每一个模板 digits[i] = roi # 初始化卷积核 rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) #读取输入图像,预处理 image = cv2.imread(args["image"]) cv_show('image', image) image = myutils.resize(image, width=300) #调整大小 gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 转为灰度图 cv_show('gray', gray) #礼帽操作,突出更明亮的区域 tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) cv_show('tophat', tophat) # gradX = cv2.Sobel( tophat, ddepth=cv2.CV_32F, dx=1, dy=0, #ksize=-1相当于用3*3的 ksize=-1) gradX = np.absolute(gradX) #绝对值
for (i, c) in enumerate(contours): # c 是每个轮廓的终点坐标 讲一个可遍历的数据对象组合成一个索引序列 (x, y, w, h) = cv.boundingRect(c) # 计算外接矩形, resize 成合适大小 # 扣模板 roi = gray_tem[y:y + h, x:x + w] # 每个roi对应一个数字 roi = cv.resize(roi, (57, 85)) # 模板拆分数字 digits[i] = roi # 每个数字对应一个模板 # image of detecting # 初始化卷积核 rectKernel = cv.getStructuringElement(cv.MORPH_RECT, (9, 3)) # sqKernel = cv.getStructuringElement(cv.MORPH_RECT, (5, 5)) # # read image # cv_show("ori_img", img) # pre-processing image img = myutils.resize(img, width=300) gray_img = cv.cvtColor(img, cv.COLOR_BGR2GRAY) # cv_show("gray_img", gray_img) # top_hat operation 把轮廓高亮处显示出来 文字等作为毛刺突出 top_hat = cv.morphologyEx(gray_img, cv.MORPH_TOPHAT, rectKernel) # cv_show("top_hat", top_hat) # sobel 算子 进行轮廓计算 gradX = cv.Sobel(top_hat, ddepth=cv.CV_32F, dx=1, dy=0, ksize=-1) # ksize=-1 相当于用3*3的模板 # 对X方向进行归一化 只对x方向进行轮廓计算是因为 从X方向获得我们要的文字信息 gradX = np.absolute(gradX) # calculate |gradx| (minVal, maxVal) = (np.min(gradX), np.max(gradX)) gradX = (255 * ((gradX - minVal) / (maxVal - minVal))) gradX = gradX.astype("uint8") print(np.array(gradX).shape) # cv_show("input_sobel_gradx", gradX)
def cv_credit_card(img,image): FIRST_NUMBER = { #字典 "3":"American Express", "4":"Visa", "5":"MasterCart", "6":"Discover Card", } #cv_show('template',img) gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转为灰度图 #cv_show('gray',gray) binary = cv2.threshold(gray,10,255,cv2.THRESH_BINARY_INV)[1] #注意阈值二值化函数返回的参数有两个!! #cv_show('binary',binary) #计算轮廓 #cv2.findContours()函数接受的参数为二值图。cv2.RETR_EXTERNAL只检测最外围的图像,cv2.CHAIN_APPROX_SIMPLE只保留中点坐标 #返回的list中每个元素都是图像中的一个轮廓 refCnts,hierarchy = cv2.findContours(binary.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img,refCnts,-1,(0,0,255),3) #画出轮廓 #cv_show('img',img) #从左到右排序。0-9 refCnts = myutils.sort_contours(refCnts,method="left-to-right")[0] digits= {} for (i,c) in enumerate(refCnts): #计算外接矩形 (x,y,w,h) = cv2.boundingRect(c) #截取图像 roi = binary[y:y+h,x:x+w] #重新设定大小 roi = cv2.resize(roi,(57,88)) #设定digits digits[i]=roi ###以上为模板的处理,以下为图片处理 #初始化卷积核 rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(9,3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5)) #cv_show('image',image) image = myutils.resize(image,width=300) image_gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY) #转化为灰度图 image_tophat = cv2.morphologyEx(image_gray,cv2.MORPH_TOPHAT,rectKernel) #礼帽处理,突出更明亮的区域 #cv_show('tophat',image_tophat) gradX = cv_sobel_x(image_tophat) #水平方向梯度滤波处理 #cv_show('gradX',gradX) gradX = cv2.morphologyEx(gradX,cv2.MORPH_CLOSE,rectKernel) #闭操作,让数字连在一起 #cv_show('gradX_MORPH_CLOSE',gradX) image_threshold = cv2.threshold(gradX,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] #THRESH_OTSU自动寻找合适的阈值,适合双峰,需把阈值下限设为0 #cv_show('image_threshold',image_threshold) image_threshold = cv2.morphologyEx(image_threshold,cv2.MORPH_CLOSE,sqKernel) threshCnts,hierarchy = cv2.findContours(image_threshold.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #计算最外层轮廓 cnts = threshCnts cur_img = image.copy() cv2.drawContours(cur_img,cnts,-1,(0,0,255),3) #画出轮廓 #cv_show('cur_img',cur_img) locs=[] #轮廓位置 for (i,c) in enumerate(cnts): (x,y,w,h) = cv2.boundingRect(c) #寻找矩形 ar = w/float(h) #求宽和高的比例 if ar>2.5 and ar<4.0: #把不符合的筛出去 if(w>40 and w <55)and(h>10 and h <20): locs.append((x,y,w,h)) locs = sorted(locs,key=lambda x:x[0]) #排个序 output = [] for (i,(gX,gY,gW,gH)) in enumerate(locs): groupOutput = [] group = image_gray[gY - 5:gY + gH + 5,gX-5:gX + gW + 5] group = cv2.threshold(group,0,255,cv2.THRESH_BINARY|cv2.THRESH_OTSU)[1] #自适应二值化处理 digitCnts,hierarchy = cv2.findContours(group.copy(),cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) #计算最外层轮廓 digitCnts = contours.sort_contours(digitCnts,method = "left-to-right")[0] for c in digitCnts: (x,y,w,h) = cv2.boundingRect(c) roi = group[y:y+h,x:x+w] roi = cv2.resize(roi,(57,88)) #cv_show('roi',roi) #print(roi) #匹配度 scores=[] for (digit,digitROI) in digits.items(): #遍历求匹配度,在模板中计算每一个得分 result = cv2.matchTemplate(roi,digitROI,cv2.TM_CCOEFF) (_,score,_,_) = cv2.minMaxLoc(result) scores.append(score) #得到最合适的数字 groupOutput.append(str(np.argmax(scores))) #画出来 cv2.rectangle(image,(gX-5,gY-5),(gX+gW+5,gY+gH+5),(0,0,255),1) cv2.putText(image, "".join(groupOutput),(gX,gY-15),cv2.FONT_HERSHEY_SIMPLEX,0.65,(0,0,255),2) output.extend(groupOutput) return image,output
def process_the_target_image(srcImage,ref_dict): # 初始化卷积核 rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 读取输入图像,预处理 image = cv2.imread(srcImage) # cv_show('image', image) image = myutils.resize(image, width=300) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # cv_show('gray', gray) # 礼帽操作,突出更明亮的区域 tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) # cv_show('tophat', tophat) # 计算X方向的梯度,突出edage gradX = cv2.Sobel(tophat, ddepth=cv2.CV_32F, dx=1, dy=0, # ksize=-1相当于用3*3的 ksize=-1) #对梯度进行归一化操作 gradX = np.absolute(gradX) (minVal, maxVal) = (np.min(gradX), np.max(gradX)) gradX = (255 * ((gradX - minVal) / (maxVal - minVal))) gradX = gradX.astype("uint8") print(np.array(gradX).shape) # cv_show('gradX', gradX) # 通过闭操作(先膨胀,再腐蚀)将数字连在一起 gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel) # cv_show('gradX', gradX) # THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0 thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] # cv_show('thresh', thresh) # 再来一个闭操作 thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) # 再来一个闭操作 # cv_show('thresh2', thresh) # 计算轮廓 thresh_, threshCnts, hierarchy = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = threshCnts cur_img = image.copy() cv2.drawContours(cur_img, cnts, -1, (0, 0, 255), 3) # cv_show('img', cur_img) locs = [] # 遍历轮廓 for (i, c) in enumerate(cnts): # 计算外接矩形 (x, y, w, h) = cv2.boundingRect(c) #计算长宽比 ar = w / float(h) # 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组 #比较长宽比 if ar > 2.5 and ar < 4.0: #比较w,h具体长度 if (w > 40 and w < 55) and (h > 10 and h < 20): # 符合的留下来 locs.append((x, y, w, h)) print(len(locs)) # 将符合的轮廓从左到右排序,空间顺序 locs = sorted(locs, key=lambda x: x[0]) #展示一下结果 my_curImage = image.copy() for boudingbox in locs: cv2.rectangle(my_curImage,(boudingbox[0],boudingbox[1]),(boudingbox[0]+boudingbox[2],boudingbox[1]+boudingbox[3]), (0,0,255),2) # cv_show("rect",my_curImage) '''提取每个boundingbox的图片信息''' output=[] # 遍历每一个轮廓中的数字 for (i, (gX, gY, gW, gH)) in enumerate(locs): # initialize the list of group digits groupOutput = [] # 根据坐标提取每一个组 # 稍微扩充一下这个roi group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5] # cv_show('group', group) # 预处理,OTSU阈值化 ret,group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) # cv_show('group', group) # 计算每一组的轮廓 group_, digitCnts, hierarchy = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) #对轮廓进行空间排序 digitCnts = myutils.sort_contours(digitCnts, method="left-to-right")[0] #显示这个轮廓 # mygroup=group.copy() # cv2.drawContours(mygroup, digitCnts, -1, (0, 0, 255), 3) # cv_show("group_contours",mygroup) # 计算每一组中的每一个数值 for c in digitCnts: # 找到当前数值的轮廓,resize成合适的的大小 (x, y, w, h) = cv2.boundingRect(c) roi = group[y:y + h, x:x + w] roi = cv2.resize(roi, (57, 88)) # cv_show('roi', roi) # 计算匹配得分 scores = [] # 在模板中计算每一个得分 for (digit, digitROI) in ref_dict.items(): # 模板匹配 ''' cv2.TM_CCOEFF (系数匹配法) cv2.TM_CCOEFF_NORMED(相关系数匹配法) cv2.TM_CCORR (相关匹配法) cv2.TM_CCORR_NORMED (归一化相关匹配法) cv2.TM_SQDIFF (平方差匹配法) cv2.TM_SQDIFF_NORMED (归一化平方差匹配法 ''' result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF) #根据 匹配方法不同,选择最大还是最小 (minval, maxval, minloc,maxloc) = cv2.minMaxLoc(result) scores.append(maxval) # 得到最合适的数字 groupOutput.append(str(np.argmax(scores))) # 画出来 cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1) cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) # 得到结果 output.extend(groupOutput) cv_show("img",image) return output
default="/mnt/dissertation_work/rawfish_dataset", help="input path") args = vars(ap.parse_args()) rootDir = args["input"] outputDir = '/mnt/dissertation_work/resizedfish/resized' + str( args["width"]) + 'x' + str(args["height"]) dim = (args["width"], args["height"]) for dirName, subDirs, fileList in os.walk(rootDir): # skip the root directory if len(subDirs) > 0: continue else: saveDir = os.path.join(outputDir, os.path.basename(dirName)) if not os.path.exists(saveDir): os.makedirs(os.path.join(outputDir, os.path.basename(dirName))) print("Creating directory {}".format(saveDir)) for i, img in enumerate(fileList): img_path = os.path.join(dirName, img) load_img = cv2.imread(img_path) resized_img = resize(load_img, dim[0], dim[1]) cv2.imwrite(os.path.join(saveDir, os.path.basename(img)), resized_img) print("Resizing image {} of {}".format(i + 1, len(fileList)), end='\r') print() print("Finished with {}".format(os.path.basename(dirName))) print("Resizing done")
#人脸数据 def face_detect_demo(image): gray = cv.cvtColor(image, cv.COLOR_BGR2GRAY) face_detector = cv.CascadeClassifier( r"F:\project\Python\house predict\haarcascade_frontalface_alt_tree.xml" ) faces = face_detector.detectMultiScale(gray, 1.1, 2) #后两个参数调整可提高人脸检测成功率 for x, y, w, h in faces: cv.rectangle(image, (x, y), (x + w, y + h), (0, 0, 255), 2) cv.imshow("result", image) print("--------------Hellp world!---------------") src = cv.imread(r"F:\project\Python\house predict\test.jpg") #type: cv src = myutils.resize(src, width=1600) cv.namedWindow("result", cv.WINDOW_AUTOSIZE) # capture = cv.VideoCapture(0) # while True: # ret, frame = capture.read() # frame = cv.flip(frame, 1) # break; # # face_detect_demo(frame) # # c = cv.waitKey(10) # # if 27 == c: # # break # #face_detect_demo(frame) cv.namedWindow("input image", cv.WINDOW_AUTOSIZE)
def read_process_image(image_path, digits): # 构造特定大小和形状的结构元素,用于图像形态学处理 rectKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (9, 3)) sqKernel = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)) # 读取输入图像,预处理 image = cv2.imread(image_path) image = myutils.resize(image, width=300) print(image.shape) gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY) # 礼帽操作,突出更明亮的区域(原始输入-开运算:得到毛刺) tophat = cv2.morphologyEx(gray, cv2.MORPH_TOPHAT, rectKernel) cv_show("", tophat) #得到像素水平方向的梯度 gradX = cv2.Sobel( tophat, ddepth=cv2.CV_32F, dx=1, dy=0, # ksize=-1相当于用3*3的 ksize=-1) gradX = np.absolute(gradX) (minVal, maxVal) = (np.min(gradX), np.max(gradX)) gradX = (255 * ((gradX - minVal) / (maxVal - minVal))) gradX = gradX.astype("uint8") # 通过闭操作(先膨胀,再腐蚀)将数字连在一起 gradX = cv2.morphologyEx(gradX, cv2.MORPH_CLOSE, rectKernel) cv_show("", gradX) # THRESH_OTSU会自动寻找合适的阈值,适合双峰,需把阈值参数设置为0 thresh = cv2.threshold(gradX, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] cv_show("", thresh) # 再来一个闭操作 thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, sqKernel) # 再来一个闭操作 cv_show("", thresh) # 计算轮廓 _, threshCnts, _ = cv2.findContours(thresh.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cnts = threshCnts cur_img = image.copy() locs = [] # 遍历轮廓 for (i, c) in enumerate(cnts): # 计算矩形 (x, y, w, h) = cv2.boundingRect(c) ar = w / float(h) # 选择合适的区域,根据实际任务来,这里的基本都是四个数字一组 if ar > 2.5 and ar < 4.0: if (w > 40 and w < 55) and (h > 10 and h < 20): # 符合的留下来 locs.append((x, y, w, h)) # 将符合的轮廓从左到右排序 locs = sorted(locs, key=lambda x: x[0]) output = [] # 遍历每一个轮廓中的数字 for (i, (gX, gY, gW, gH)) in enumerate(locs): # initialize the list of group digits groupOutput = [] # 根据坐标提取每一个组 group = gray[gY - 5:gY + gH + 5, gX - 5:gX + gW + 5] # cv_show('group', group) # 预处理 group = cv2.threshold(group, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1] # cv_show('group', group) # 计算每一组的轮廓 _, digitCnts, _ = cv2.findContours(group.copy(), cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) digitCnts = contours.sort_contours(digitCnts, method="left-to-right")[0] # 计算每一组中的每一个数值 for c in digitCnts: # 找到当前数值的轮廓,resize成合适的的大小 (x, y, w, h) = cv2.boundingRect(c) roi = group[y:y + h, x:x + w] roi = cv2.resize(roi, (template_high, template_wigth)) # 计算匹配得分 scores = [] # 在模板中计算每一个得分 for (digit, digitROI) in digits.items(): # 模板匹配 result = cv2.matchTemplate(roi, digitROI, cv2.TM_CCOEFF) (_, score, _, _) = cv2.minMaxLoc(result) scores.append(score) # 得到最合适的数字 groupOutput.append(str(np.argmax(scores))) # 画出来 cv2.rectangle(image, (gX - 5, gY - 5), (gX + gW + 5, gY + gH + 5), (0, 0, 255), 1) cv2.putText(image, "".join(groupOutput), (gX, gY - 15), cv2.FONT_HERSHEY_SIMPLEX, 0.65, (0, 0, 255), 2) # 得到结果 output.extend(groupOutput) # 打印结果 print("Credit Card Type: {}".format(FIRST_NUMBER[output[0]])) print("Credit Card #: {}".format("".join(output)))