├── Interface.py ├── LICENSE ├── README.md ├── face_detection ├── __init__.py ├── arcsoft │ ├── AFD_FSDKLibrary.py │ ├── AFR_FSDKLibrary.py │ ├── ASVL_COLOR_FORMAT.py │ ├── CLibrary.py │ ├── __init__.py │ └── utils │ │ ├── ImageLoader.py │ │ └── __init__.py ├── facepp_detection.py ├── hrFace.py ├── libarcsoft_fsdk_face_detection.dll └── paddleHub.py ├── images ├── __init__.py ├── bell.jpg ├── cabinet.jpg ├── camera.jpg ├── house.jpg ├── meCROP.png └── memory_pic.py ├── imgs_detection ├── emotion.jpg ├── example1.png └── lena.jpg ├── login.py ├── processing ├── ImgProcessing.py └── __init__.py ├── requirements.txt ├── screenshots ├── Logarithmic_gray_scale_transformation.png ├── Login.png ├── RGB_histogram.png ├── Sobel.png ├── img_add.png ├── median_filtering.png ├── modifications.png ├── n_value.png └── register.png └── usrs_info.pickle /Interface.py: -------------------------------------------------------------------------------- 1 | import tkinter 2 | import tkinter.messagebox 3 | from tkinter.constants import * 4 | 5 | from PIL import Image, ImageTk 6 | import cv2 7 | 8 | from processing.ImgProcessing import * 9 | 10 | 11 | class ttsx(object): 12 | def __init__(self,face1,tk,rate=-10): 13 | self.rate = rate 14 | self.panel = None 15 | self.face1 = face1 # 这个是传进来的frame()对象, 依赖于tk()对象 16 | self.SELF = tk # 这个是tk()对象 17 | 18 | def createICO(self): 19 | self.img1 = ImageTk.PhotoImage(Image.open('./images/house.jpg')) 20 | self.img2 = ImageTk.PhotoImage(Image.open('./images/bell.jpg')) 21 | self.img3 = ImageTk.PhotoImage(Image.open('./images/camera.jpg')) 22 | self.img4 = ImageTk.PhotoImage(Image.open('./images/cabinet.jpg')) 23 | 24 | # 绑定快捷键 25 | def AssertERRORToMakeFuckingICOShowing(self): 26 | # assert False 27 | # try: 28 | # assert False 29 | # raise NameError 30 | # except Exception as e: 31 | # print("nvm") 32 | # assert False 33 | # raise NameError 34 | raise NotImplementedError 35 | 36 | # 创建菜单 37 | def createMenu(self): 38 | '''只支持两层嵌套''' 39 | menus = ['文件', '编辑', '工具', '帮助'] 40 | items = [['打开', '保存', '另存为...'], 41 | 42 | ['撤销', '-', '剪切', '复制', '粘贴', '删除', '选择所有',['更多...','数据', '图表', '统计']], 43 | 44 | [['灰度变换', 'n值化', '线性化', ['非线性化', '对数变换', '伽马变换']], 45 | '绘制直方图', '图像相加', ['图像滤波', '均值滤波', '中值滤波'], '图像锐化', 46 | ['人脸检测', 'HOG模型', 'CNN模型', '虹软SDK', 'face++SDK', 'PyramidBox_Lite']], 47 | 48 | ['检查更新', '关于作者']] 49 | callbacks = [[FILE.dialog1, FILE.dialog2, FILE.dialog3], 50 | 51 | [EDIT.dialog1, None, EDIT.dialog1, EDIT.dialog1, EDIT.dialog1, 52 | EDIT.dialog1, EDIT.dialog1, [EDIT.dialog1, EDIT.dialog1, EDIT.dialog1]], 53 | 54 | [[TOOLS.grey_n, TOOLS.grey_lin, [TOOLS.grey_lg, TOOLS.grey_gamma]], 55 | TOOLS.Hist_RGB, TOOLS.ImgPlus, [TOOLS.AvgFiltering, TOOLS.MedFiltering], TOOLS.Sobel_Sharpening, 56 | [TOOLS.HOGFaceRecognition, TOOLS.CNNFaceRecognition, TOOLS.ArcSoft, TOOLS.FacePPSDK, TOOLS.paddleHub1]], 57 | 58 | [HELP.Update, HELP.ABOUT]] 59 | icos = [[self.img1, self.img2, self.img3], 60 | 61 | [self.img1, None, self.img2, self.img3, self.img2, self.img4, self.img2, [self.img3, self.img2, self.img4]], 62 | 63 | [[self.img1, self.img2, [self.img1, self.img3]], self.img3, self.img4, [self.img1, self.img2], 64 | self.img2, [self.img3, self.img1, self.img2, self.img4, self.img3]], 65 | 66 | [self.img1, self.img2]] 67 | 68 | menubar = tkinter.Menu(self.SELF) 69 | # 创建每一个菜单项, 目前4个 70 | for i,x in enumerate(menus): 71 | m = tkinter.Menu(menubar, tearoff=0) 72 | # 创建每个菜单项的下拉项 73 | for item, callback, ico in zip(items[i], callbacks[i], icos[i]): 74 | # 如果这个下拉项还有嵌套项 75 | if isinstance(item, list): 76 | sm = tkinter.Menu(menubar, tearoff=0) 77 | # 就默认第一个是项名,后面的是嵌套项 78 | for subitem, subcallback, subico in zip(item[1:], callback, ico): 79 | # 继续判断是不是有嵌套项 80 | if isinstance(subitem, list): 81 | xm = tkinter.Menu(menubar, tearoff=0) 82 | for subsubitem, subsubcallback, subsubico in zip(subitem[1:], subcallback, subico): 83 | if subsubitem == '-': 84 | xm.add_separator() 85 | else: 86 | xm.add_command(label=subsubitem, command=subsubcallback, image=subsubico, compound='left') 87 | sm.add_cascade(label=subitem[0], menu=xm) 88 | elif subitem == '-': 89 | sm.add_separator() 90 | else: 91 | sm.add_command(label=subitem, command=subcallback, image=subico, compound='left') 92 | m.add_cascade(label=item[0], menu=sm) 93 | elif item == '-': 94 | m.add_separator() 95 | else: 96 | m.add_command(label=item, command=callback, image=ico, compound='left') 97 | menubar.add_cascade(label=x, menu=m) 98 | self.SELF.config(menu=menubar) 99 | 100 | #初始化窗体 101 | def tkMain(self,title,h=400,w=300): 102 | self.SELF.title(title) 103 | self.SELF.geometry("565x350") # 桌子, 即tk()对象 104 | 105 | # 读入菜单要用的图片 106 | self.createICO() 107 | # 创建菜单 108 | self.createMenu() 109 | self.AssertERRORToMakeFuckingICOShowing() 110 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 luka 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Digital Image Processing 2 | 基于Python语言的数字图像处理程序,包含登录界面和工具栏。主要功能包括:灰度变换(n值化、线性化、非线性化);绘制RGB直方图;两幅任意大小、通道图像相加;均值滤波和中值滤波;Sobel算子锐化;集成人脸识别API如face_recognition库、虹软SDK、face++、paddlehub库 3 | 4 | A Windows application based on tkinter of Python for image processing purposes, which is part of my final project of course *Digital Image Processing and Experiment* in CAU(China Agricultural University). 5 | 6 | ## Details 7 | The main functions include: 8 | - Grayscale transformation (N value, linearization, nonlinearization) 9 | - Plot RGB histogram 10 | - Add two images on pixel-level (images could be arbitrary size and channel) 11 | - Mean filtering and Median filtering 12 | - Sobel operator sharpness 13 | - Face detection based on multiple API: 14 | - face_recognition packages of Python 15 | - arcsoft SDK 16 | - face++ API 17 | - Paddlehub 18 | 19 | ## Requirements 20 | ``` 21 | $ pip install -r requirements.txt 22 | ``` 23 | ## Run 24 | ``` 25 | $ python login.py 26 | ``` 27 | ## Results Show(incomplete) 28 | 29 | |(●'◡'●)|Operation|Result| 30 | |---|---|---- 31 | |

1

|

Login Interface(password is 123)

| 32 | |

2

|

Register Interface

| 33 | |

3

|

N Value

| 34 | |

4

|

Images Add

| 35 | |

5

|

RGB_histogram

| 36 | |

6

|

Median Filtering

| 37 | |

7

|

Logarithmic Grayscale Transformation

| 38 | |

8

|

Sobel

| 39 | |

9

|

Face Detection

| 40 | 41 | ## Notes 42 | The arcsoft face detection API need you to appy and then you can use. [Here](https://blog.csdn.net/weixin_42815846/article/details/106882614) is a tutorial to teach you how to do that. 43 | 44 | When you get your `APPID` and `FD_SDKKEY` successfully, you can replace the two lines below with them within the [hrFace.py](https://github.com/leaving-voider/Digital-Image-Processing/blob/master/face_detection/hrFace.py) file. 45 | ![img](https://github.com/leaving-voider/Digital-Image-Processing/blob/master/screenshots/modifications.png) 46 | -------------------------------------------------------------------------------- /face_detection/__init__.py: -------------------------------------------------------------------------------- 1 | from face_detection import hrFace 2 | from face_detection import facepp_detection 3 | from face_detection import paddleHub -------------------------------------------------------------------------------- /face_detection/arcsoft/AFD_FSDKLibrary.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | import platform 3 | from ctypes import * 4 | from . import MRECT,ASVLOFFSCREEN 5 | 6 | class AFD_FSDK_FACERES(Structure): 7 | _fields_ = [(u'nFace',c_int32),(u'rcFace',POINTER(MRECT)),(u'lfaceOrient',POINTER(c_int32))] 8 | 9 | class AFD_FSDK_Version(Structure): 10 | _fields_ = [(u'lCodebase',c_int32),(u'lMajor',c_int32),(u'lMinor',c_int32),(u'lBuild',c_int32), 11 | (u'Version',c_char_p),(u'BuildDate',c_char_p),(u'CopyRight',c_char_p)] 12 | 13 | AFD_FSDK_OPF_0_ONLY = 0x1; # 0; 0; ... 14 | AFD_FSDK_OPF_90_ONLY = 0x2; # 90; 90; ... 15 | AFD_FSDK_OPF_270_ONLY = 0x3; # 270; 270; ... 16 | AFD_FSDK_OPF_180_ONLY = 0x4; # 180; 180; ... 17 | AFD_FSDK_OPF_0_HIGHER_EXT = 0x5; # 0; 90; 270; 180; 0; 90; 270; 180; ... 18 | 19 | AFD_FSDK_FOC_0 = 0x1;# 0 degree 20 | AFD_FSDK_FOC_90 = 0x2; # 90 degree 21 | AFD_FSDK_FOC_270 = 0x3; # 270 degree 22 | AFD_FSDK_FOC_180 = 0x4; # 180 degree 23 | AFD_FSDK_FOC_30 = 0x5; # 30 degree 24 | AFD_FSDK_FOC_60 = 0x6; # 60 degree 25 | AFD_FSDK_FOC_120 = 0x7; # 120 degree 26 | AFD_FSDK_FOC_150 = 0x8; # 150 degree 27 | AFD_FSDK_FOC_210 = 0x9; # 210 degree 28 | AFD_FSDK_FOC_240 = 0xa; # 240 degree 29 | AFD_FSDK_FOC_300 = 0xb; # 300 degree 30 | AFD_FSDK_FOC_330 = 0xc; # 330 degree 31 | 32 | if platform.system() == u'Windows': 33 | internalLibrary = CDLL(u'./face_detection/libarcsoft_fsdk_face_detection.dll') 34 | else: 35 | internalLibrary = CDLL(u'./face_detection/libarcsoft_fsdk_face_detection.so') 36 | 37 | AFD_FSDK_InitialFaceEngine = internalLibrary.AFD_FSDK_InitialFaceEngine 38 | AFD_FSDK_UninitialFaceEngine = internalLibrary.AFD_FSDK_UninitialFaceEngine 39 | AFD_FSDK_StillImageFaceDetection = internalLibrary.AFD_FSDK_StillImageFaceDetection 40 | AFD_FSDK_GetVersion = internalLibrary.AFD_FSDK_GetVersion 41 | 42 | AFD_FSDK_InitialFaceEngine.restype = c_long 43 | AFD_FSDK_InitialFaceEngine.argtypes = (c_char_p,c_char_p,c_void_p,c_int32,POINTER(c_void_p),c_int32,c_int32,c_int32) 44 | AFD_FSDK_UninitialFaceEngine.restype = c_long 45 | AFD_FSDK_UninitialFaceEngine.argtypes = (c_void_p,) 46 | AFD_FSDK_StillImageFaceDetection.restype = c_long 47 | AFD_FSDK_StillImageFaceDetection.argtypes = (c_void_p,POINTER(ASVLOFFSCREEN),POINTER(POINTER(AFD_FSDK_FACERES))) 48 | AFD_FSDK_GetVersion.restype = POINTER(AFD_FSDK_Version) 49 | AFD_FSDK_GetVersion.argtypes =(c_void_p,) -------------------------------------------------------------------------------- /face_detection/arcsoft/AFR_FSDKLibrary.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | import platform 3 | from ctypes import * 4 | from . import MRECT,ASVLOFFSCREEN 5 | from . import CLibrary 6 | 7 | class AFR_FSDK_Version(Structure): 8 | _fields_ = [(u'lCodebase',c_int32),(u'lMajor',c_int32),(u'lMinor',c_int32),(u'lBuild',c_int32),(u'lFeatureLevel',c_int32), 9 | (u'Version',c_char_p),(u'BuildDate',c_char_p),(u'CopyRight',c_char_p)] 10 | 11 | class AFR_FSDK_FACEINPUT(Structure): 12 | _fields_ = [(u'rcFace',MRECT),(u'lOrient',c_int32)] 13 | 14 | class AFR_FSDK_FACEMODEL(Structure): 15 | _fields_ = [(u'pbFeature',c_void_p),(u'lFeatureSize',c_int32)] 16 | def __init__(self): 17 | self.bAllocByMalloc = False 18 | Structure.__init__(self) 19 | def deepCopy(self): 20 | if(self.pbFeature == 0): 21 | raise Exception(u'invalid feature') 22 | feature = AFR_FSDK_FACEMODEL() 23 | feature.bAllocByMalloc = True 24 | feature.lFeatureSize = self.lFeatureSize 25 | feature.pbFeature = CLibrary.malloc(feature.lFeatureSize) 26 | CLibrary.memcpy(feature.pbFeature,self.pbFeature,feature.lFeatureSize) 27 | return feature 28 | def freeUnmanaged(self): 29 | if self.bAllocByMalloc and (self.pbFeature != 0): 30 | CLibrary.free(self.pbFeature) 31 | self.pbFeature = 0 32 | def __del__(self): 33 | self.freeUnmanaged() 34 | #print(u'gc feature freeUnmanaged') 35 | @staticmethod 36 | def fromByteArray(byteArrayFeature): 37 | if byteArrayFeature == None: 38 | raise Exception(u'invalid byteArray') 39 | feature = AFR_FSDK_FACEMODEL() 40 | feature.lFeatureSize = len(byteArrayFeature) 41 | feature.bAllocByMalloc = True 42 | featureData = create_string_buffer(byteArrayFeature) 43 | feature.pbFeature = CLibrary.malloc(feature.lFeatureSize) 44 | CLibrary.memcpy(feature.pbFeature,cast(featureData,c_void_p),feature.lFeatureSize) 45 | return feature 46 | 47 | def toByteArray(self): 48 | if(self.pbFeature == 0): 49 | raise Exception(u'invalid feature') 50 | featureData = create_string_buffer(self.lFeatureSize) 51 | CLibrary.memcpy(cast(featureData,c_void_p),self.pbFeature,self.lFeatureSize) 52 | return bytes(bytearray(featureData)) 53 | 54 | 55 | if platform.system() == u'Windows': 56 | internalLibrary = CDLL(u'libarcsoft_fsdk_face_recognition.dll') 57 | else: 58 | internalLibrary = CDLL(u'libarcsoft_fsdk_face_recognition.so') 59 | 60 | AFR_FSDK_InitialEngine = internalLibrary.AFR_FSDK_InitialEngine 61 | AFR_FSDK_UninitialEngine = internalLibrary.AFR_FSDK_UninitialEngine 62 | AFR_FSDK_ExtractFRFeature = internalLibrary.AFR_FSDK_ExtractFRFeature 63 | AFR_FSDK_FacePairMatching = internalLibrary.AFR_FSDK_FacePairMatching 64 | AFR_FSDK_GetVersion = internalLibrary.AFR_FSDK_GetVersion 65 | 66 | AFR_FSDK_InitialEngine.restype = c_long 67 | AFR_FSDK_InitialEngine.argtypes = (c_char_p,c_char_p,c_void_p,c_int32,POINTER(c_void_p)) 68 | AFR_FSDK_UninitialEngine.restype = c_long 69 | AFR_FSDK_UninitialEngine.argtypes = (c_void_p,) 70 | AFR_FSDK_ExtractFRFeature.restype = c_long 71 | AFR_FSDK_ExtractFRFeature.argtypes = (c_void_p,POINTER(ASVLOFFSCREEN),POINTER(AFR_FSDK_FACEINPUT),POINTER(AFR_FSDK_FACEMODEL)) 72 | AFR_FSDK_FacePairMatching.restype = c_long 73 | AFR_FSDK_FacePairMatching.argtypes = (c_void_p,POINTER(AFR_FSDK_FACEMODEL),POINTER(AFR_FSDK_FACEMODEL),POINTER(c_float)) 74 | AFR_FSDK_GetVersion.restype = POINTER(AFR_FSDK_Version) 75 | AFR_FSDK_GetVersion.argtypes =(c_void_p,) 76 | -------------------------------------------------------------------------------- /face_detection/arcsoft/ASVL_COLOR_FORMAT.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | 3 | ASVL_PAF_I420 = 0x601 4 | ASVL_PAF_NV12 = 0x801 5 | ASVL_PAF_NV21 = 0x802 6 | ASVL_PAF_YUYV = 0x501 7 | ASVL_PAF_RGB24_B8G8R8 = 0x201 8 | -------------------------------------------------------------------------------- /face_detection/arcsoft/CLibrary.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | from ctypes import * 3 | import platform 4 | 5 | if platform.system() == u'Windows': 6 | internalLibrary = cdll.msvcrt 7 | else: 8 | internalLibrary = CDLL(u'libc.so') 9 | 10 | malloc = internalLibrary.malloc 11 | free = internalLibrary.free 12 | memcpy = internalLibrary.memcpy 13 | 14 | malloc.restype = c_void_p 15 | malloc.argtypes =(c_size_t,) 16 | free.restype = None 17 | free.argtypes = (c_void_p,) 18 | memcpy.restype = c_void_p 19 | memcpy.argtypes =(c_void_p,c_void_p,c_size_t) -------------------------------------------------------------------------------- /face_detection/arcsoft/__init__.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | 3 | from ctypes import * 4 | 5 | c_ubyte_p = POINTER(c_ubyte) 6 | 7 | class MRECT(Structure): 8 | _fields_ = [(u'left',c_int32),(u'top',c_int32),(u'right',c_int32),(u'bottom',c_int32)] 9 | 10 | class ASVLOFFSCREEN(Structure): 11 | _fields_ = [(u'u32PixelArrayFormat',c_uint32),(u'i32Width',c_int32),(u'i32Height',c_int32), 12 | (u'ppu8Plane',c_ubyte_p*4),(u'pi32Pitch',c_int32*4)] 13 | def __init__(self): 14 | Structure.__init__(self) 15 | self.gc_ppu8Plane0 = None 16 | self.gc_ppu8Plane1 = None 17 | self.gc_ppu8Plane2 = None 18 | self.gc_ppu8Plane3 = None 19 | 20 | class FaceInfo: 21 | def __init__(self,l,t,r,b,o): 22 | self.left = l; 23 | self.top = t; 24 | self.right = r; 25 | self.bottom = b; 26 | self.orient = o; 27 | 28 | 29 | -------------------------------------------------------------------------------- /face_detection/arcsoft/utils/ImageLoader.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | import io 3 | from PIL import Image 4 | from . import BufferInfo 5 | 6 | USING_FLOAT = True 7 | 8 | def BGRA2I420(bgr_buffer, width, height): 9 | yuv = bytearray(width * height * 3 // 2) 10 | u_offset = width * height 11 | y_offset = width * height * 5 // 4 12 | 13 | for i in range(0, height): 14 | for j in range(0, width): 15 | b = ord(bgr_buffer[54+(i*width+j)*3+0]) 16 | g = ord(bgr_buffer[54+(i*width+j)*3+1]) 17 | r = ord(bgr_buffer[54+(i*width+j)*3+2]) 18 | 19 | y = ((77 * r + 150 * g + 29 * b + 128) >> 8) 20 | u = (((-43) * r - 84 * g + 127 * b + 128) >> 8) + 128 21 | v = ((127 * r - 106 * g - 21 * b + 128) >> 8) + 128 22 | 23 | y = 0 if y < 0 else (255 if y > 255 else (y & 0xFF)) 24 | u = 0 if u < 0 else (255 if u > 255 else (u & 0xFF)) 25 | v = 0 if v < 0 else (255 if v > 255 else (v & 0xFF)) 26 | 27 | yuv[i * width + j] = y 28 | yuv[u_offset + (i >> 1) * (width >> 1) + (j >> 1)] = u 29 | yuv[y_offset + (i >> 1) * (width >> 1) + (j >> 1)] = v 30 | 31 | return bytes(yuv) 32 | 33 | def BGRA2I420_float(bgr_buffer, width, height): 34 | yuv = bytearray(width * height * 3 // 2) 35 | u_offset = width * height 36 | y_offset = width * height * 5 // 4 37 | 38 | for i in range(0, height): 39 | for j in range(0, width): 40 | b = ord(bgr_buffer[54+(i*width+j)*3+0]) 41 | g = ord(bgr_buffer[54+(i*width+j)*3+1]) 42 | r = ord(bgr_buffer[54+(i*width+j)*3+2]) 43 | 44 | y = (0.299 * r + 0.587 * g + 0.114 * b) 45 | u = (-0.169) * r - 0.331 * g + 0.499 * b + 128.0 46 | v = 0.499 * r - 0.418 * g - 0.0813 * b + 128.0 47 | 48 | yuv[i * width + j] = int(y) 49 | yuv[u_offset + (i >> 1) * (width >> 1) + (j >> 1)] = int(u) 50 | yuv[y_offset + (i >> 1) * (width >> 1) + (j >> 1)] = int(v) 51 | 52 | return bytes(yuv) 53 | 54 | def getI420FromFile(filePath): 55 | oldimg = Image.open(filePath) 56 | 57 | # BMP 4 byte align 58 | newWidth = oldimg.width& 0xFFFFFFFC 59 | newHeight = oldimg.height& 0xFFFFFFFE 60 | if(newWidth != oldimg.width) or (newHeight != oldimg.height): 61 | crop_area = (0, 0, newWidth, newHeight) 62 | img = oldimg.crop(crop_area) 63 | else: 64 | img = oldimg 65 | BMP_bytes = io.BytesIO() 66 | img.transpose(Image.FLIP_TOP_BOTTOM).convert('RGB').save(BMP_bytes, format='BMP') 67 | bgr_buffer = BMP_bytes.getvalue() 68 | 69 | if USING_FLOAT: 70 | yuv = BGRA2I420_float(bgr_buffer, newWidth, newHeight) 71 | else: 72 | yuv = BGRA2I420(bgr_buffer, newWidth, newHeight) 73 | return BufferInfo(newWidth, newHeight, yuv) 74 | 75 | def getBGRFromFile(filePath): 76 | oldimg = Image.open(filePath) 77 | 78 | # BMP 4 byte align 79 | newWidth = oldimg.width& 0xFFFFFFFC 80 | newHeight = oldimg.height& 0xFFFFFFFE 81 | if(newWidth != oldimg.width) or (newHeight != oldimg.height): 82 | crop_area = (0, 0, newWidth, newHeight) 83 | img = oldimg.crop(crop_area) 84 | else: 85 | img = oldimg 86 | 87 | BMP_bytes = io.BytesIO() 88 | img.transpose(Image.FLIP_TOP_BOTTOM).convert('RGB').save(BMP_bytes, format='BMP') 89 | bgr_buffer = bytes(BMP_bytes.getvalue()[54:]) 90 | 91 | return BufferInfo(newWidth, newHeight, bgr_buffer) 92 | -------------------------------------------------------------------------------- /face_detection/arcsoft/utils/__init__.py: -------------------------------------------------------------------------------- 1 | #-*- encoding=utf-8 -*- 2 | 3 | class BufferInfo: 4 | def __init__(self,w, h, buf): 5 | self.width = w; 6 | self.height = h; 7 | self.buffer = buf; -------------------------------------------------------------------------------- /face_detection/facepp_detection.py: -------------------------------------------------------------------------------- 1 | import requests 2 | from json import JSONDecoder 3 | import cv2 4 | import time 5 | 6 | def Facepp(imgPath): 7 | t1=time.time() 8 | http_url = "https://api-cn.faceplusplus.com/facepp/v3/detect" 9 | key ="VcgZF6hAdAX9S0I6kABipTUw-bUmJjmf" 10 | secret ="HXPsyDty5vabuvCig3sOCXOpkFBP7dp2" 11 | filepath = imgPath 12 | #list=['qiyi.jpg','chenduling.jpg','fan.jpg'] 13 | frame=cv2.imread(filepath) 14 | data = {"api_key": key, "api_secret": secret, "return_landmark": "1","return_attributes":"gender"} 15 | files = {"image_file": open(filepath, "rb")} 16 | response = requests.post(http_url, data=data, files=files) 17 | 18 | req_con = response.content.decode('utf-8') 19 | req_dict = JSONDecoder().decode(req_con) 20 | 21 | #print(req_dict) 22 | face_rectangles=[] 23 | #print(req_dict['faces'][0]['face_rectangle']) 24 | 25 | # print(req_dict) #调用返回的 26 | # print(req_dict['faces']) 27 | for face in req_dict['faces']: #使用循环遍历 reqdict里面的faces部分 把里面提取到的脸的定位给获取出来 28 | if 'face_rectangle' in face.keys(): 29 | face_rectangles.append(face['face_rectangle']) 30 | print('检测到{}张人脸'.format(len(face_rectangles))) 31 | for i in face_rectangles: 32 | w=i['width'] 33 | t=i['top'] 34 | l=i['left'] 35 | h=i['height'] 36 | print('width: {}, top: {}, left:{}, height:{}'.format(w, t, l, h)) 37 | cv2.rectangle(frame, (l, t), (w+l, h+t), (0, 0, 255), 2) #opencv的标框函数 38 | 39 | print('运行时间是{}'.format(time.time()-t1)) 40 | # cv2.imshow('tuxiang',frame) 41 | # cv2.waitKey(1) 42 | 43 | # time.sleep(5) 44 | return frame 45 | -------------------------------------------------------------------------------- /face_detection/hrFace.py: -------------------------------------------------------------------------------- 1 | from face_detection.arcsoft import CLibrary, ASVL_COLOR_FORMAT, ASVLOFFSCREEN,c_ubyte_p,FaceInfo 2 | from face_detection.arcsoft.utils import BufferInfo, ImageLoader 3 | from face_detection.arcsoft.AFD_FSDKLibrary import * 4 | from ctypes import * 5 | import traceback 6 | import cv2 7 | import time 8 | 9 | def detection(imgPath): 10 | APPID = c_char_p(b'hereshouldbeyourAPPID') 11 | FD_SDKKEY = c_char_p(b'hereshouldbeyourFD_SDKKEY') 12 | FD_WORKBUF_SIZE = 20 * 1024 * 1024 13 | MAX_FACE_NUM = 50 14 | bUseYUVFile = False 15 | bUseBGRToEngine = True 16 | 17 | def doFaceDetection(hFDEngine, inputImg): #对图像中的人脸进行定位 18 | faceInfo = [] 19 | 20 | pFaceRes = POINTER(AFD_FSDK_FACERES)() 21 | ret = AFD_FSDK_StillImageFaceDetection(hFDEngine, byref(inputImg), byref(pFaceRes)) 22 | #ret 为0 23 | 24 | if ret != 0: 25 | print(u'AFD_FSDK_StillImageFaceDetection 0x{0:x}'.format(ret)) 26 | return faceInfo 27 | faceRes = pFaceRes.contents 28 | print('******') 29 | 30 | facecont=faceRes.nFace #faceRes 是一个对象所以 输出会是一个地址值 而他的一个属性nface是表示的是人脸的个数 31 | print('%d 个人脸' %facecont) 32 | 33 | 34 | if faceRes.nFace > 0: 35 | for i in range(0, faceRes.nFace): 36 | rect = faceRes.rcFace[i] 37 | orient = faceRes.lfaceOrient[i] 38 | faceInfo.append(FaceInfo(rect.left,rect.top,rect.right,rect.bottom,orient)) 39 | 40 | 41 | return faceInfo 42 | 43 | def loadImage(filePath): 44 | 45 | inputImg = ASVLOFFSCREEN() 46 | 47 | if bUseBGRToEngine: #true 48 | bufferInfo = ImageLoader.getBGRFromFile(filePath) 49 | inputImg.u32PixelArrayFormat = ASVL_COLOR_FORMAT.ASVL_PAF_RGB24_B8G8R8 50 | inputImg.i32Width = bufferInfo.width 51 | inputImg.i32Height = bufferInfo.height 52 | inputImg.pi32Pitch[0] = bufferInfo.width*3 53 | inputImg.ppu8Plane[0] = cast(bufferInfo.buffer, c_ubyte_p) 54 | inputImg.ppu8Plane[1] = cast(0, c_ubyte_p) 55 | inputImg.ppu8Plane[2] = cast(0, c_ubyte_p) 56 | inputImg.ppu8Plane[3] = cast(0, c_ubyte_p) 57 | else: 58 | bufferInfo = ImageLoader.getI420FromFile(filePath) 59 | inputImg.u32PixelArrayFormat = ASVL_COLOR_FORMAT.ASVL_PAF_I420 60 | inputImg.i32Width = bufferInfo.width 61 | inputImg.i32Height = bufferInfo.height 62 | inputImg.pi32Pitch[0] = inputImg.i32Width 63 | inputImg.pi32Pitch[1] = inputImg.i32Width // 2 64 | inputImg.pi32Pitch[2] = inputImg.i32Width // 2 65 | inputImg.ppu8Plane[0] = cast(bufferInfo.buffer, c_ubyte_p) 66 | inputImg.ppu8Plane[1] = cast(addressof(inputImg.ppu8Plane[0].contents) + (inputImg.pi32Pitch[0] * inputImg.i32Height), c_ubyte_p) 67 | inputImg.ppu8Plane[2] = cast(addressof(inputImg.ppu8Plane[1].contents) + (inputImg.pi32Pitch[1] * inputImg.i32Height // 2), c_ubyte_p) 68 | inputImg.ppu8Plane[3] = cast(0, c_ubyte_p) 69 | inputImg.gc_ppu8Plane0 = bufferInfo.buffer 70 | 71 | return inputImg 72 | 73 | t=time.time() 74 | print(u'#####################################################') 75 | 76 | # init Engine 77 | pFDWorkMem = CLibrary.malloc(c_size_t(FD_WORKBUF_SIZE)) 78 | hFDEngine = c_void_p() 79 | ret = AFD_FSDK_InitialFaceEngine(APPID, FD_SDKKEY, pFDWorkMem, c_int32(FD_WORKBUF_SIZE), byref(hFDEngine), AFD_FSDK_OPF_0_HIGHER_EXT, 32, MAX_FACE_NUM) 80 | #ret 为0 81 | if ret != 0: 82 | CLibrary.free(pFDWorkMem) 83 | print(u'AFD_FSDK_InitialFaceEngine ret 0x{:x}'.format(ret)) 84 | exit(0) 85 | #--------------------------------以上部分两个函数以及主函数的几条语句不变----------------------------------------------------------- 86 | 87 | filePath = imgPath 88 | inputImg = loadImage(filePath) #调用loadImage函数 返回一种格式(目前还不知道这种格式是什么) 89 | 90 | frame=cv2.imread(filePath) 91 | # do Face Detect 92 | 93 | faceInfos = doFaceDetection(hFDEngine, inputImg) #调用dofaceDetection函数 进行图像处理检测人脸 94 | #print('faceInfos %s'% faceInfos[0]) 95 | 96 | for i in range(0, len(faceInfos)): 97 | rect = faceInfos[i] 98 | print(u'{} ({} {} {} {}) orient {}'.format(i, rect.left, rect.top, rect.right, rect.bottom, rect.orient)) 99 | cv2.rectangle(frame, (rect.left, rect.top), (rect.right, rect.bottom), (0, 0, 255), 2) 100 | # cropimg=frame[rect.top:rect.bottom,rect.left:rect.right]# 使用opencv裁剪照片 把人脸的照片裁剪下来 101 | # cv2.imwrite('crop-photo/'+str(i)+'.jpg',cropimg) # 把人脸照片保存下来 102 | 103 | AFD_FSDK_UninitialFaceEngine(hFDEngine) # release Engine 104 | # cv2.imshow('tuxiang',frame) 105 | # cv2.waitKey(1) 106 | print('所用时间为{} '.format(time.time()-t)) #不进行保存图片 0.12s 保存图片0.16s 107 | # time.sleep(1) 108 | 109 | CLibrary.free(pFDWorkMem) 110 | print(u'#####################################################') 111 | return frame -------------------------------------------------------------------------------- /face_detection/libarcsoft_fsdk_face_detection.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/face_detection/libarcsoft_fsdk_face_detection.dll -------------------------------------------------------------------------------- /face_detection/paddleHub.py: -------------------------------------------------------------------------------- 1 | import paddlehub as hub 2 | import cv2 3 | 4 | def paddlePyramidBox_Lite(imgPath): 5 | module = hub.Module(name="pyramidbox_lite_server") 6 | 7 | test_img_path = imgPath 8 | img = cv2.imread(test_img_path) 9 | # 使用字典形式输入 10 | input_dict = {"data": [img]} 11 | 12 | results = module.face_detection(data=input_dict) 13 | 14 | det = results[0]['data'] 15 | for condition in det: 16 | left, top, right, bottom, confidence = condition['left'], condition['top'], \ 17 | condition['right'], condition['bottom'], condition['confidence'] 18 | # 画出一个框,框住脸 19 | cv2.rectangle(img, (int(left), int(top)), (int(right), int(bottom)), (0, 255, 255), 2) 20 | font = cv2.FONT_HERSHEY_DUPLEX 21 | cv2.putText(img, '%2.2f' % confidence, (int(left) + 4, int(bottom) + 24), font, 1.0, 22 | (255, 255, 255), 1) 23 | 24 | return img -------------------------------------------------------------------------------- /images/__init__.py: -------------------------------------------------------------------------------- 1 | from images import memory_pic -------------------------------------------------------------------------------- /images/bell.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/images/bell.jpg -------------------------------------------------------------------------------- /images/cabinet.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/images/cabinet.jpg -------------------------------------------------------------------------------- /images/camera.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/images/camera.jpg -------------------------------------------------------------------------------- /images/house.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/images/house.jpg -------------------------------------------------------------------------------- /images/meCROP.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/images/meCROP.png -------------------------------------------------------------------------------- /images/memory_pic.py: -------------------------------------------------------------------------------- 1 | welcome_gif = "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PeydjjzJJftF8+asVPuvLjy6gwyuE2y1hQvA/BYIAVDKvxMAd4x62wTJW2wRUeS0sBzLe4tsAEa42PrE0RzDhsykJ3e4J7jBHNzIGSFJfDa9lyTFN5nHnnorGKGNfFu6Zoykf8ykTCyzRUV1YMvHwAwzp8wR3pzF4cwRA4Ic+docVogRc7rCaeyhtkqf76zE1nxyNksR/L8Mx1IQAB4hnZvFyh1RFSU8KIWCz/1K0F1rthwKzdtXdU5qEXpgAvXMLSWQMhOtW99sSemDyg6RPjB0vduhGq3oabKssgVNdf9qy9uKyCaUvv/DzR9xQi9dawSlvcy8GW9CHx4Bmf7607assscrfdjsyERNOEYdEgOkRFq8QM2bEVDSFvgzGUxNgCmbztW6v2XbeIIsfQ091M/b1a7hZuEDV+dTFSqHEqVh06nhHDJ9OkpRpEiMi1a7ybeq0Iu0eiUNHBySNv+BdSbUuM7WEvjBFj+gOJtNFzNCElLNoZksuKZ7sNqabFmNEXoQ2RjzH8McOsGRFVZA2SDxPfyWzRSv3c1K0Z7sbK16qthbS9pcOxZBPdcbwQJRyitRwAIr8hCvQTqykds6/YqYPNzSdhUsS76BLNwLXZwcgb4p/SF23dxCoXZ7a6uzJ59J/MdlrN3aDb7HRni03RAtMB6JAiEtQN4zE4jOXK5TjdjCrdh8WgUkQBKB0AKsDSP/0QLSrd84EdpTuN5i0dipLRLoqx+rRB4sMN4OHhVVUZbcaLZJtpaDzWaYyR4BUALR3eF4gc6VuXrzzOIyHmfR9+JVV30znuMC3dE2fnIKq+NALhFQyNs9jmxV2OBBnuQQXuQVnuROjrg1zuTe/eRUjnqvmIJqieNVvuW+eeV0Nq7lXB7mdLTblVmFJS7mOs4YUseNqXB1aP7mCkFyRC7XKYfkcP7k9FZsrKdvaX3nYT5sem64zHbZfl7o95FpYtFphr7oDPHcsTEbjB7pkj7plF7pln7pmJ7pmr7pnN7pnv7poB7qoj7qpF7qpn7qqB4SAQEAIf5rRklMRSBJREVOVElUWQ0KQ3JlYXRlZCBvciBtb2RpZmllZCBieQ0KYW4gdW5pZGVudGlmaWVkIHVzZXIgb2YgYW4gdW5yZWdpc3RlcmVkIGNvcHkgb2YgR0lGIENvbnN0cnVjdGlvbiBTZXQAIf7qVU5SRUdJU1RFUkVEIFNIQVJFV0FSRQ0KDQpBc3NlbWJsZWQgd2l0aCBHSUYgQ29uc3RydWN0aW9uIFNldDoNCg0KQWxjaGVteSBNaW5kd29ya3MgSW5jLg0KQm94IDUwMA0KQmVldG9uLCBPTg0KTDBHIDFBMA0KQ0FOQURBLg0KDQpodHRwOi8vd3d3Lm1pbmR3b3Jrc2hvcC5jb20NCg0KVGhpcyBjb21tZW50IHdpbGwgbm90IGFwcGVhciBpbiBmaWxlcyBjcmVhdGVkIHdpdGggYSByZWdpc3RlcmVkIHZlcnNpb24uACH/C0dJRkNPTm5iMS4wAgIADggAAgADAAAAAAAAAAAACHd3MS5naWYADggAAgAFAAAAAAAAAAAACHd3Mi5naWYAADs=" 2 | -------------------------------------------------------------------------------- /imgs_detection/emotion.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/imgs_detection/emotion.jpg -------------------------------------------------------------------------------- /imgs_detection/example1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/imgs_detection/example1.png -------------------------------------------------------------------------------- /imgs_detection/lena.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/imgs_detection/lena.jpg -------------------------------------------------------------------------------- /login.py: -------------------------------------------------------------------------------- 1 | # -*- coding:utf-8 -*- 2 | import pickle # 存放数据的模块 3 | import tkinter 4 | import tkinter.messagebox 5 | import os 6 | import sys 7 | 8 | import Interface 9 | # import win32com.client # 微软这个服务器 10 | from tkinter.constants import * 11 | from tkinter import filedialog 12 | import tkinter.messagebox 13 | import pyglet 14 | import os 15 | # from pydub import AudioSegment # 音频格式转换 16 | from images.memory_pic import * # 导入图片 17 | import base64 # 编码 18 | 19 | # 注册功能函数 20 | def usr_sign_up(): 21 | # 用户信息数据 录入函数 22 | def sign_to_Python(): 23 | # 获取输入信息 24 | np = new_pwd.get() 25 | npf = new_pwd_confirm.get() 26 | nn = new_name.get() 27 | 28 | # 打开保存用户信息的文件 29 | try: 30 | with open("usrs_info.pickle", "rb") as usr_file: 31 | exist_usr_info = pickle.load(usr_file) 32 | # 如果没有 新建一个 33 | except FileNotFoundError: 34 | with open("usrs_info.pickle", "wb") as usr_file: # with open with语句可以自动关闭资源 35 | usrs_info = {"admin": "admin"} # 以字典的形式保存账户和密码 36 | pickle.dump(usrs_info, usr_file) # 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件 37 | exist_usr_info = usrs_info 38 | # 密码两次输入不一致 39 | if np != npf: 40 | tkinter.messagebox.showerror("Error", "Password and confirm password must be the same!") 41 | # 账户已被注册过 42 | elif nn in exist_usr_info: 43 | tkinter.messagebox.showerror("Error", "The user has already signed up! ") 44 | # 成功录入 45 | else: 46 | exist_usr_info[nn] = np 47 | with open("usrs_info.pickle", "wb") as usr_file: 48 | pickle.dump(exist_usr_info, usr_file) 49 | tkinter.messagebox.showinfo("Welcome", "You have successfully signed up!") 50 | # 销毁新创建的顶级窗口 51 | window_sign_up.destroy() 52 | 53 | # 没有任何传入,新建顶级窗口 用于注册 54 | window_sign_up = tkinter.Toplevel() 55 | window_sign_up.geometry("350x200") 56 | window_sign_up.title("sign up window") 57 | 58 | # 设置用户名的StringVar 59 | new_name = tkinter.StringVar() 60 | new_name.set("example@python.com") 61 | 62 | # 在顶级窗口加Label 输入口 63 | tkinter.Label(window_sign_up, text="User name:").place(x=10, y=10) 64 | entry_new_name = tkinter.Entry(window_sign_up, textvariable=new_name) 65 | entry_new_name.place(x=150, y=10) 66 | 67 | # 设置密码的StringVar 68 | new_pwd = tkinter.StringVar() 69 | # 添加密码输入口 70 | tkinter.Label(window_sign_up, text="Password:").place(x=10, y=50) 71 | entry_usr_pwd = tkinter.Entry(window_sign_up, textvariable=new_pwd, show='*') 72 | entry_usr_pwd.place(x=150, y=50) 73 | 74 | new_pwd_confirm = tkinter.StringVar() 75 | # 添加confirm输入口 76 | tkinter.Label(window_sign_up, text="Confirm password:").place(x=10, y=90) 77 | entry_usr_pwd_confirm = tkinter.Entry(window_sign_up, textvariable=new_pwd_confirm, show='*') 78 | entry_usr_pwd_confirm.place(x=150, y=90) 79 | 80 | # 确认注册按钮 81 | btn_confirm_sign_up = tkinter.Button(window_sign_up, text="Sign up", command=sign_to_Python) 82 | btn_confirm_sign_up.place(x=150, y=130) 83 | 84 | 85 | # 在这里面设置了最初创建的tk()对象的size并将其传入initface类 86 | class basedesk(): 87 | def __init__(self,master): 88 | # 界面布局,master是传入的tk()对象 89 | self.window = master 90 | self.window.title("LOGIN WINDOW") 91 | self.window.geometry("450x300") 92 | self.window.iconphoto(False, tkinter.PhotoImage(file='./images/meCROP.png')) 93 | # 再把此tk()对象传入interface() 94 | initface(self.window) 95 | 96 | class initface(): 97 | def __init__(self,master): 98 | # tk是最开始创建的tk()对象 99 | self.tk = master 100 | 101 | # 基准界面initface,对象是框架控件Frame,tk()是Frame的父容器 102 | # 框架(Frame)控件在屏幕上显示一个矩形区域,多用来作为容器 103 | self.initface = tkinter.Frame(self.tk, height=400, width=500) 104 | # pack是 布局管理模块 105 | self.initface.pack() 106 | 107 | # 第一张桌布,画布(Canvas)组件和 html5 中的画布一样,都是用来绘图的 108 | # 可以将图形,文本,小部件或框架放置在画布上 109 | self.canvas = tkinter.Canvas(self.initface, height=300, width=400) 110 | # 获取封面图片 111 | self.get_pic(welcome_gif, 'welcome.gif') # 创造图片 112 | # 创建图像 113 | self.image_file = tkinter.PhotoImage(file='welcome.gif') 114 | self.canvas.create_image(0, 0, anchor='nw', image=self.image_file) 115 | self.canvas.pack(side='top') 116 | os.remove('welcome.gif') # 用完就删,生成的中间文件 117 | 118 | # 标签控件 119 | Label1 = tkinter.Label(self.initface, text='User name:') 120 | Label1.place(x=50, y=150) # place也是一个位置管理方法 121 | # Label1.pack() 122 | 123 | # 标签控件 124 | self.Label2 = tkinter.Label(self.initface, text='Password name:') 125 | self.Label2.place(x=50, y=190) 126 | 127 | # 设置保存 账号密码的stringVar()对象 128 | self.var_usr_name = tkinter.StringVar() 129 | self.var_usr_name.set('example@python.com') # 设置默认值 130 | 131 | self.var_usr_pwd = tkinter.StringVar() 132 | 133 | # 输入控件;用于显示简单的文本内容, textvariable是文本框的值,是一个StringVar()对象 134 | self.entry_usr_name = tkinter.Entry(self.initface, textvariable=self.var_usr_name) 135 | self.entry_usr_name.place(x=160, y=150) 136 | self.entry_usr_pwd = tkinter.Entry(self.initface, show='*', textvariable=self.var_usr_pwd) 137 | self.entry_usr_pwd.place(x=160, y=190) 138 | 139 | # login 按钮 140 | btn_login = tkinter.Button(self.initface, text="Login", command=self.usr_login) 141 | btn_login.place(x=170, y=230) 142 | 143 | # sign up 注册按钮 144 | btn_sign_up = tkinter.Button(self.initface, text="Sign up", command=usr_sign_up) 145 | btn_sign_up.place(x=270, y=230) 146 | # btn_sign_up.pack() 147 | 148 | # 退出程序按钮 149 | btn = tkinter.Button(self.initface, text='EXIT', command=self.change) 150 | btn.pack() 151 | 152 | # 获取封面图片的函数 153 | def get_pic(self, pic_code, pic_name): 154 | image = open(pic_name, 'wb') 155 | # 解码后写到当前文件下 156 | image.write(base64.b64decode(pic_code)) 157 | image.close() 158 | 159 | # 点击登录后调用函数 160 | def usr_login(self): 161 | # 获取输入的 账户信息 162 | usr_name = self.var_usr_name.get() 163 | usr_pwd = self.var_usr_pwd.get() 164 | 165 | # 打开保存用户信息的文件 166 | try: 167 | with open("usrs_info.pickle", "rb") as usr_file: 168 | usrs_info = pickle.load(usr_file) 169 | # 如果没有 新建一个 170 | except FileNotFoundError: 171 | with open("usrs_info.pickle", "wb") as usr_file: # with open with语句可以自动关闭资源 172 | usrs_info = {"admin": "admin"} # 以字典的形式保存账户和密码 173 | pickle.dump(usrs_info, usr_file) # 将数据通过特殊的形式转换为只有python语言认识的字符串,并写入文件 174 | 175 | # 登录成功/失败 处理程序段 176 | if usr_name in usrs_info: 177 | if usr_pwd == usrs_info[usr_name]: 178 | tkinter.messagebox.showinfo(title="Welcome", message="How are you! " + usr_name) 179 | # 摧毁tk()对象下登录框架Frame(), 这样依赖于frame创建的所有canvas、按钮等等都也被摧毁 180 | self.initface.destroy() 181 | # 将tk()对象传入 182 | Interfaced(self.tk) 183 | else: 184 | tkinter.messagebox.showerror(message="Error,your password is wrong,try again") 185 | else: 186 | is_sign_up = tkinter.messagebox.askyesno("Welcome", "You have not sign up yet.Sign up today?") 187 | if is_sign_up: 188 | usr_sign_up() 189 | 190 | def change(self,): 191 | sys.exit(1) 192 | 193 | 194 | class Interfaced(): 195 | def __init__(self, master): 196 | # 保存传入的tk()对象 197 | self.master = master 198 | # self.master.config(bg='blue') 199 | # sys.exit(1) 200 | # 依赖于最初的tk()创建一个新的框架对象frame() 201 | self.face1 = tkinter.Frame(self.master,) 202 | self.face1.pack() 203 | # btn_back = tkinter.Button(self.face1,text='face1 back',command=self.back) 204 | # btn_back.pack() 205 | # 将此框架和tk()传入Interface.py文件中的ttsx类 206 | ttx = Interface.ttsx(self.face1, self.master) 207 | # 调用该类的tkMain函数,进行初始化窗体操作 208 | ttx.tkMain("My Digital Image Processing") 209 | 210 | def back(self): 211 | self.face1.destroy() 212 | initface(self.master) 213 | 214 | 215 | if __name__ == '__main__': 216 | root = tkinter.Tk() 217 | basedesk(root) 218 | # 窗体主循环 219 | root.mainloop() -------------------------------------------------------------------------------- /processing/ImgProcessing.py: -------------------------------------------------------------------------------- 1 | from tkinter import filedialog, simpledialog 2 | # import win32com.client # 微软这个服务器 3 | import tkinter 4 | from tkinter.constants import * 5 | import math 6 | import tkinter.messagebox 7 | import pyglet 8 | import os 9 | from PIL import Image, ImageTk 10 | # from pydub import AudioSegment # 音频格式转换 11 | from images.memory_pic import * # 导入图片 12 | import base64 # 编码 13 | import numpy as np 14 | import matplotlib.pyplot as plt 15 | 16 | from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg 17 | from matplotlib.figure import Figure 18 | import cv2 19 | 20 | # 导入face_recogntion模块 21 | import face_recognition 22 | import time 23 | # 导入虹软检测模块 24 | from face_detection.hrFace import * 25 | from face_detection.facepp_detection import * 26 | # 导入paddlehub模块 27 | from face_detection.paddleHub import * 28 | 29 | # 主图片路径 30 | Img_path = "" 31 | # 专门用于打开图片的toplevel窗口 32 | topWin = 0 33 | 34 | # n值化灰度变换专用窗口 35 | GreyNvaluesWin = 0 36 | # 线性化灰度变换专用窗口 37 | GreyLinearWin = 0 38 | # 非线性化对数变换窗口 39 | GreyLogWin = 0 40 | # 非线性化指数变换窗口 41 | GreyExWin = 0 42 | 43 | # GRB三通道直方图专用窗口 44 | RgbHistWin = 0 45 | 46 | # 图像相加的第二个图片路径 47 | ImgPlus_path = "" 48 | # 图片相加的第二个图片专用窗口 49 | ImgPlueSecWin = 0 50 | # 相加的图片专用窗口 51 | ImgPlusResultWin = 0 52 | 53 | # 滤波专用椒盐窗口(暂未使用) 54 | PepperSaltWin = 0 55 | # 均值滤波专用窗口 56 | AvgFilterWin = 0 57 | # 中值滤波专用窗口 58 | MedFilterWin = 0 59 | 60 | # Sobel图像锐化 61 | SobelSharpenWin = 0 62 | 63 | # 人脸检测 64 | FaceRecogWinn = 0 65 | 66 | 67 | #################################################################################################################################### 68 | #################################################################################################################################### 69 | ###################################### FILE CLASS ######################################### 70 | #################################################################################################################################### 71 | #################################################################################################################################### 72 | 73 | def is_chinese(Str): 74 | """ 75 | 检查整个字符串是否包含中文 76 | :param string: 需要检查的字符串 77 | :return: bool 78 | """ 79 | for ch in Str: 80 | if u'\u4e00' <= ch <= u'\u9fff': 81 | return True 82 | return False 83 | 84 | class FILE: 85 | 86 | 87 | def template(): 88 | '''各种窗口''' 89 | #res = messagebox.askokcancel(title='标题', message='提示信息。。。', default=messagebox.CANCEL) # default=messagebox.CANCEL,指定默认焦点位置,另 ABORT/RETRY/IGNORE/OK/CANCEL/YES/NO 90 | #res = messagebox.showinfo(title='标题', message='提示信息。。。') 91 | #res = messagebox.showwarning(title='标题', message='提示信息。。。') 92 | #res = messagebox.showerror(title='标题', message='提示信息。。。') 93 | #res = messagebox.askquestion(title='标题', message='提示信息。。。') 94 | #res = messagebox.askyesno(title='标题', message='提示信息。。。') 95 | #res = messagebox.askyesnocancel(title='标题', message='提示信息。。。') 96 | #res = messagebox.askretrycancel(title='标题', message='提示信息。。。') 97 | 98 | #res = filedialog.askdirectory() 99 | #res = filedialog.askopenfile(filetypes=[('xml', '*.xml')]) 100 | #res = filedialog.askopenfiles() 101 | #res = filedialog.askopenfilename() 102 | #res = filedialog.askopenfilenames() 103 | #res = filedialog.asksaveasfile() 104 | #res = filedialog.asksaveasfilename() 105 | 106 | #res = simpledialog.askinteger(title='整数', prompt='输入一个整数', initialvalue=100) 107 | #res = simpledialog.askfloat(titlee='实数', prompt='输入一个实数', minvalue=0, maxvalue=11) 108 | res = simpledialog.askstring(title='字符串', prompt='输入一个字符串') 109 | 110 | #res = colorchooser.askcolor() 111 | print(res) 112 | return 113 | 114 | ''' 115 | 文件 116 | ['打开', '保存', '另存为...'] 117 | ''' 118 | # 打开文件 119 | def dialog1(): 120 | global Img_path, topWin 121 | 122 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 123 | 124 | if not filePath: 125 | tkinter.messagebox.showerror(message="Cannot open this file!") 126 | return 127 | 128 | if (is_chinese(filePath)): 129 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 130 | return 131 | 132 | try: 133 | topWin.destroy() 134 | except Exception as e: 135 | print("NVM") 136 | finally: 137 | topWin = tkinter.Toplevel() 138 | topWin.attributes('-topmost', True) 139 | # topWin = tkinter.Toplevel() 140 | topWin.geometry("360x240") 141 | topWin.resizable(True,True) # 可缩放 142 | topWin.title("IMAGE") 143 | # ImageWindow.withdraw() 144 | LabelPic = tkinter.Label(topWin, text="IMG", width=360, height=240) 145 | # im = Image.open(filePath) 146 | im = cv2.imread(filePath) 147 | im = im[:, :, ::-1] 148 | 149 | image = ImageTk.PhotoImage(Image.fromarray(im)) 150 | LabelPic.image = image 151 | LabelPic['image'] = image 152 | # cv2.imshow('image', image) 153 | def changeSize(event): 154 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(im, (event.width, event.height)))) 155 | LabelPic.image = image1 156 | LabelPic['image'] = image1 157 | LabelPic.bind('', changeSize) 158 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 159 | # 记录便于图像处理 160 | Img_path = filePath 161 | # Img_path[1].append(ImageWindow) 162 | # TopWin.append(ImageWindow) 163 | # print(filePath, ImageWindow) 164 | # print(Img_path) 165 | return 166 | 167 | # 保存文件 168 | def dialog2(): 169 | return 170 | 171 | # 另存为 172 | def dialog3(): 173 | return 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | #################################################################################################################################### 183 | #################################################################################################################################### 184 | ###################################### EDIT CLASS ######################################### 185 | #################################################################################################################################### 186 | #################################################################################################################################### 187 | 188 | 189 | class EDIT: 190 | ''' 191 | 编辑 192 | ['撤销', '-', '剪切', '复制', '粘贴', '删除', '选择所有',['更多...','数据', '图表', '统计']] 193 | ''' 194 | def dialog1(): 195 | return 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | #################################################################################################################################### 206 | #################################################################################################################################### 207 | ###################################### TOOLS CLASS ######################################## 208 | #################################################################################################################################### 209 | #################################################################################################################################### 210 | 211 | class TOOLS: 212 | ''' 213 | 工具 214 | [['灰度变换', 'n值化', '线性化', ['非线性化', '对数变换', '伽马变换']], '绘制直方图', '图像相加', '图像滤波', '图像锐化'] 215 | ''' 216 | # n值化 217 | def grey_n(): 218 | global Img_path, GreyNvaluesWin 219 | print("n值化") 220 | if(Img_path==""): 221 | return 222 | 223 | # n值化灰度变换函数 224 | def N_values_TRANS(n, img): 225 | dst = img*n 226 | return dst 227 | # 得到img的array 228 | img=np.array(Image.open(Img_path).convert('L')) 229 | 230 | # 读取n 231 | n = simpledialog.askinteger(title='变换函数 Fx = Fx*n', prompt='输入n', initialvalue=2) 232 | 233 | # 进行n值化灰度变换 234 | img = N_values_TRANS(n, img) 235 | 236 | # 创建toplevel窗口 237 | try: 238 | GreyNvaluesWin.destroy() 239 | except Exception as e: 240 | print("NVM") 241 | finally: 242 | GreyNvaluesWin = tkinter.Toplevel() 243 | GreyNvaluesWin.attributes('-topmost', True) 244 | GreyNvaluesWin.geometry("360x240") 245 | GreyNvaluesWin.resizable(True,True) # 可缩放 246 | GreyNvaluesWin.title("N值化灰度变换") 247 | 248 | LabelPic = tkinter.Label(GreyNvaluesWin, text="IMG", width=360, height=240) 249 | 250 | image = ImageTk.PhotoImage(Image.fromarray(img)) 251 | LabelPic.image = image 252 | LabelPic['image'] = image 253 | # cv2.imshow('image', image) 254 | def changeSize(event): 255 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 256 | LabelPic.image = image1 257 | LabelPic['image'] = image1 258 | LabelPic.bind('', changeSize) 259 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 260 | 261 | return 262 | 263 | # 线性化 264 | def grey_lin(): 265 | global Img_path, GreyLinearWin 266 | print("线性化") 267 | if(Img_path==""): 268 | return 269 | 270 | # 线性化灰度处理函数 271 | def Contrast_and_Brightness(a, b, img): 272 | blank = np.ones(img.shape, img.dtype) 273 | # dst = alpha * img + beta * blank 274 | dst = img*a + b*blank 275 | return dst 276 | # 得到img的array 277 | img=np.array(Image.open(Img_path).convert('L')) 278 | 279 | # 读取alpha、beta 280 | a = simpledialog.askfloat(title='变换函数 Fx = Fx*a + b', prompt='输入a', minvalue=0, maxvalue=100) 281 | b = simpledialog.askfloat(title='变换函数 Fx = Fx*a + b', prompt='输入b', minvalue=0, maxvalue=100) 282 | 283 | # 进行变换 284 | img = Contrast_and_Brightness(a,b,img) 285 | 286 | # 创建toplevel窗口 287 | try: 288 | GreyLinearWin.destroy() 289 | except Exception as e: 290 | print("NVM") 291 | finally: 292 | GreyLinearWin = tkinter.Toplevel() 293 | GreyLinearWin.attributes('-topmost', True) 294 | GreyLinearWin.geometry("360x240") 295 | GreyLinearWin.resizable(True,True) # 可缩放 296 | GreyLinearWin.title("线性化灰度变换") 297 | 298 | LabelPic = tkinter.Label(GreyLinearWin, text="IMG", width=360, height=240) 299 | 300 | image = ImageTk.PhotoImage(Image.fromarray(img)) 301 | LabelPic.image = image 302 | LabelPic['image'] = image 303 | # cv2.imshow('image', image) 304 | def changeSize(event): 305 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 306 | LabelPic.image = image1 307 | LabelPic['image'] = image1 308 | LabelPic.bind('', changeSize) 309 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 310 | 311 | return 312 | 313 | # 非线性化——对数变换 314 | def grey_lg(): 315 | global Img_path, GreyLogWin 316 | print("对数变换") 317 | if(Img_path==""): 318 | return 319 | 320 | # 对数灰度处理函数 321 | def Log_TRANS(c, img): 322 | blank = np.ones(img.shape, img.dtype) 323 | img += blank 324 | img[img==0] = 255 325 | img = np.log10(img) 326 | dst = c*img 327 | dst = dst.astype(np.uint8) 328 | return dst 329 | # 得到img的array 330 | img=np.array(Image.open(Img_path).convert('L')) 331 | 332 | # 读取c、r 333 | c = simpledialog.askinteger(title='变换函数 Fx = c*log(1+Fx)', prompt='输入c', minvalue=0, maxvalue=100) 334 | 335 | # 进行变换 336 | img = Log_TRANS(c,img) 337 | 338 | # 创建toplevel窗口 339 | try: 340 | GreyLogWin.destroy() 341 | except Exception as e: 342 | print("NVM") 343 | finally: 344 | GreyLogWin = tkinter.Toplevel() 345 | GreyLogWin.attributes('-topmost', True) 346 | GreyLogWin.geometry("360x240") 347 | GreyLogWin.resizable(True,True) # 可缩放 348 | GreyLogWin.title("对数灰度变换") 349 | 350 | LabelPic = tkinter.Label(GreyLogWin, text="IMG", width=360, height=240) 351 | 352 | image = ImageTk.PhotoImage(Image.fromarray(img)) 353 | LabelPic.image = image 354 | LabelPic['image'] = image 355 | # cv2.imshow('image', image) 356 | def changeSize(event): 357 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 358 | LabelPic.image = image1 359 | LabelPic['image'] = image1 360 | LabelPic.bind('', changeSize) 361 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 362 | 363 | return 364 | 365 | # 非线性化——伽马变换 366 | def grey_gamma(): 367 | global Img_path, GreyExWin 368 | print("伽马变换") 369 | 370 | if(Img_path==""): 371 | return 372 | 373 | # 伽马灰度处理函数 374 | def Gamma_TRANS(c, r, img): 375 | dst = c*np.power(img, r) 376 | return dst 377 | # 得到img的array 378 | img=np.array(Image.open(Img_path).convert('L')) 379 | 380 | # 读取c、r 381 | c = simpledialog.askfloat(title='变换函数 Fx = c*Fx**r', prompt='输入c', minvalue=0, maxvalue=100) 382 | r = simpledialog.askfloat(title='变换函数 Fx = c*Fx**r', prompt='输入r', minvalue=0, maxvalue=100) 383 | 384 | # 进行变换 385 | img = Gamma_TRANS(c,r,img) 386 | 387 | # 创建toplevel窗口 388 | try: 389 | GreyExWin.destroy() 390 | except Exception as e: 391 | print("NVM") 392 | finally: 393 | GreyExWin = tkinter.Toplevel() 394 | GreyExWin.attributes('-topmost', True) 395 | GreyExWin.geometry("360x240") 396 | GreyExWin.resizable(True,True) # 可缩放 397 | GreyExWin.title("伽马灰度变换") 398 | 399 | LabelPic = tkinter.Label(GreyExWin, text="IMG", width=360, height=240) 400 | 401 | image = ImageTk.PhotoImage(Image.fromarray(img)) 402 | LabelPic.image = image 403 | LabelPic['image'] = image 404 | # cv2.imshow('image', image) 405 | def changeSize(event): 406 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 407 | LabelPic.image = image1 408 | LabelPic['image'] = image1 409 | LabelPic.bind('', changeSize) 410 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 411 | 412 | return 413 | 414 | ################################################################################################################################ 415 | 416 | # RGB三通道直方图 417 | def Hist_RGB(): 418 | global Img_path, RgbHistWin 419 | print("三通道直方图") 420 | if(Img_path==""): 421 | return 422 | 423 | # 创建toplevel窗口 424 | try: 425 | RgbHistWin.destroy() 426 | except Exception as e: 427 | print("NVM") 428 | finally: 429 | RgbHistWin = tkinter.Toplevel() 430 | RgbHistWin.attributes('-topmost', True) 431 | RgbHistWin.geometry("550x400") 432 | RgbHistWin.resizable(True,True) # 可缩放 433 | RgbHistWin.title("RGB三通道直方图") 434 | 435 | # 创建figure 436 | fig = Figure(figsize=(8, 6), dpi=100) 437 | fig_plot = fig.add_subplot(111) 438 | 439 | # 创建figure中的画布,并绑定RgbHistWin 440 | canvas = FigureCanvasTkAgg(fig, RgbHistWin) 441 | canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) 442 | 443 | # 清空figure 444 | fig_plot.clear() 445 | # 得到图像 446 | img = cv2.imread(Img_path,1) 447 | color = ('b','g','r') 448 | for i,col in enumerate(color): 449 | histr = cv2.calcHist([img],[i],None,[256],[0,256]) 450 | fig_plot.plot(histr,color = col) 451 | canvas.draw() 452 | 453 | return 454 | 455 | ################################################################################################################################ 456 | 457 | # 图片相加 458 | def ImgPlus(): 459 | global Img_path, ImgPlus_path, ImgPlueSecWin, ImgPlusResultWin 460 | secondSize = 0 461 | print("图片相加") 462 | if(Img_path==""): 463 | return 464 | 465 | # 读取需要加和的图片 466 | ImgPlus_path = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 467 | 468 | if (is_chinese(ImgPlus_path)): 469 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 470 | return 471 | 472 | if not ImgPlus_path: 473 | tkinter.messagebox.showerror(message="Cannot open this file!") 474 | return 475 | try: 476 | ImgPlueSecWin.destroy() 477 | except Exception as e: 478 | print("NVM") 479 | finally: 480 | ImgPlueSecWin = tkinter.Toplevel() 481 | ImgPlueSecWin.attributes('-topmost', True) 482 | # topWin = tkinter.Toplevel() 483 | ImgPlueSecWin.geometry("360x240") 484 | ImgPlueSecWin.resizable(True,True) # 可缩放 485 | ImgPlueSecWin.title("被加的图片") 486 | LabelPic = tkinter.Label(ImgPlueSecWin, text="IMG", width=360, height=240) 487 | 488 | # 读取second图片 489 | im = cv2.imread(ImgPlus_path) 490 | secondSize = im.shape 491 | im = im[:, :, ::-1] 492 | 493 | image = ImageTk.PhotoImage(Image.fromarray(im)) 494 | LabelPic.image = image 495 | LabelPic['image'] = image 496 | def changeSize(event): 497 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(im, (event.width, event.height)))) 498 | LabelPic.image = image1 499 | LabelPic['image'] = image1 500 | LabelPic.bind('', changeSize) 501 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 502 | 503 | # 图像相加函数 504 | def IMG_PLUS(img1, img2): 505 | img1 = cv2.resize(img1, (im.shape[1], im.shape[0])) 506 | dst = img1*0.5 + img2*0.5 507 | dst = dst.astype(np.uint8) 508 | return dst 509 | # 转换图片的通道 510 | def ChannelShift(img): 511 | # 4通道转3通道 512 | if img.mode == 4: 513 | r, g, b, a = img.split() 514 | img = Image.merge("RGB", (r, g, b)) 515 | # 1 通道转3通道 516 | elif img.mode != 'RGB': 517 | img = img.convert("RGB") 518 | return img 519 | 520 | 521 | # 得到img的array 522 | img1 = Image.open(Img_path) 523 | img2 = Image.open(ImgPlus_path) 524 | 525 | img1 = np.array(ChannelShift(img1)) 526 | img2 = np.array(ChannelShift(img2)) 527 | 528 | # 进行变换 529 | img = IMG_PLUS(img1,img2) 530 | 531 | # 创建合成窗口 532 | try: 533 | ImgPlusResultWin.destroy() 534 | except Exception as e: 535 | print("NVM") 536 | finally: 537 | ImgPlusResultWin = tkinter.Toplevel() 538 | ImgPlusResultWin.attributes('-topmost', True) 539 | # topWin = tkinter.Toplevel() 540 | ImgPlusResultWin.geometry("360x240") 541 | ImgPlusResultWin.resizable(True,True) # 可缩放 542 | ImgPlusResultWin.title("加和结果图片") 543 | LabelPic2 = tkinter.Label(ImgPlusResultWin, text="IMG", width=secondSize[1], height=secondSize[0]) 544 | 545 | # img 必须(只能)是 546 | image2 = ImageTk.PhotoImage(Image.fromarray(img)) 547 | LabelPic2.image = image2 548 | LabelPic2['image'] = image2 549 | # cv2.imshow('image', image) 550 | def changeSize(event): 551 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 552 | LabelPic2.image = image1 553 | LabelPic2['image'] = image1 554 | LabelPic2.bind('', changeSize) 555 | LabelPic2.pack(fill=tkinter.BOTH, expand=tkinter.YES) 556 | 557 | return 558 | 559 | 560 | 561 | ################################################################################################################################ 562 | 563 | 564 | # 均值滤波 565 | def AvgFiltering(): 566 | global Img_path, PepperSaltWin, AvgFilterWin 567 | print("均值滤波") 568 | if(Img_path==""): 569 | return 570 | 571 | # 均值滤波处理函数 572 | def AvgFilterProc(l, img): 573 | # 按维度加和 574 | def Mysum(ThreeDimMatrix): 575 | ThreeDimMatrix = ThreeDimMatrix.sum(axis = 0) 576 | ThreeDimMatrix = ThreeDimMatrix.sum(axis = 0) 577 | return ThreeDimMatrix 578 | # 计算填充数 579 | padding = (l-1)//2 580 | # print('img', img.shape) 581 | if len(img.shape)==2: 582 | # 支持一维灰度图 583 | pad = ((padding, padding), (padding, padding)) 584 | Filter = np.ones((l, l), img.dtype) 585 | else: 586 | # 长、高填充,深度不填充 587 | pad = ((padding, padding), (padding, padding), (0,0)) 588 | # 得到filter 589 | Filter = np.ones((l, l, img.shape[2]), img.dtype) 590 | # 图片周围填充0 591 | padImg= np.pad(img, pad, 'constant', constant_values=(0, 0)) 592 | # 高 1080 593 | for i in range(padding, padImg.shape[0] - padding): 594 | # 长 1920 595 | for j in range(padding, padImg.shape[1] - padding): 596 | # 对应位相乘 597 | padImg[i][j] = Mysum(Filter * padImg[i-padding:i+padding+1, j-padding:j+padding+1])//(l ** 2) 598 | dst = padImg[padding:padImg.shape[0] - padding, padding:padImg.shape[1] - padding] #把操作完多余的0去除,保证尺寸一样大 599 | return dst 600 | # 得到img的array 601 | img=np.array(Image.open(Img_path)) 602 | 603 | # 读取l 604 | l = simpledialog.askinteger(title='滤波核大小(边长 奇数)', prompt='输入边长L', initialvalue=3, minvalue=0, maxvalue=41) 605 | if l%2==0: 606 | tkinter.messagebox.showerror(message="The length must be odd number!") 607 | return 608 | 609 | # 进行变换 610 | tkinter.messagebox.showinfo(title='Notes', message='Please be patient, the time may take a while because of Matrix Calculation') 611 | img = AvgFilterProc(l, img) 612 | 613 | # 创建toplevel窗口 614 | try: 615 | AvgFilterWin.destroy() 616 | except Exception as e: 617 | print("NVM") 618 | finally: 619 | AvgFilterWin = tkinter.Toplevel() 620 | AvgFilterWin.attributes('-topmost', True) 621 | AvgFilterWin.geometry("360x240") 622 | AvgFilterWin.resizable(True,True) # 可缩放 623 | AvgFilterWin.title("均值滤波") 624 | 625 | LabelPic = tkinter.Label(AvgFilterWin, text="IMG", width=360, height=240) 626 | 627 | image = ImageTk.PhotoImage(Image.fromarray(img)) 628 | LabelPic.image = image 629 | LabelPic['image'] = image 630 | # cv2.imshow('image', image) 631 | def changeSize(event): 632 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 633 | LabelPic.image = image1 634 | LabelPic['image'] = image1 635 | LabelPic.bind('', changeSize) 636 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 637 | 638 | return 639 | 640 | # 中值滤波 641 | def MedFiltering(): 642 | global Img_path, PepperSaltWin, MedFilterWin 643 | print("中值滤波") 644 | if(Img_path==""): 645 | return 646 | 647 | # 中值滤波处理函数 648 | def MedFilterProc(l, img): 649 | # 按维度加和 650 | def MyMedian(ThreeDimMatrix): 651 | # axis0为纵轴,1为深度轴,2为横轴,这很坑 652 | blank = 0 653 | if len(img.shape)==2: 654 | blank = np.median(ThreeDimMatrix) 655 | else: 656 | blank = np.zeros((img.shape[2])) 657 | for i in range(img.shape[2]): 658 | blank[i] = np.median(ThreeDimMatrix[:,:,i]) 659 | return blank 660 | # 计算填充数 661 | padding = (l-1)//2 662 | # print('img', img.shape) 663 | if len(img.shape)==2: 664 | # 支持一维灰度图 665 | pad = ((padding, padding), (padding, padding)) 666 | else: 667 | # 长、高填充,深度不填充 668 | pad = ((padding, padding), (padding, padding), (0,0)) 669 | # 图片周围填充0 670 | padImg= np.pad(img, pad, 'constant', constant_values=(0, 0)) 671 | print('padImg', padImg.shape) 672 | # 高 1080 673 | for i in range(padding, padImg.shape[0] - padding): 674 | # 长 1920 675 | for j in range(padding, padImg.shape[1] - padding): 676 | # 对应位相乘 677 | padImg[i][j] = MyMedian(padImg[i-padding:i+padding+1, j-padding:j+padding+1]) 678 | 679 | dst = padImg[padding:padImg.shape[0] - padding, padding:padImg.shape[1] - padding] #把操作完多余的0去除,保证尺寸一样大 680 | return dst 681 | # 得到img的array 682 | img=np.array(Image.open(Img_path)) 683 | 684 | # 读取l 685 | l = simpledialog.askinteger(title='滤波核大小(边长 奇数)', prompt='输入边长L', initialvalue=3, minvalue=0, maxvalue=41) 686 | if l%2==0: 687 | tkinter.messagebox.showerror(message="The length must be odd number!") 688 | return 689 | 690 | # 进行变换 691 | tkinter.messagebox.showinfo(title='Notes', message='Please be patient, the time may take a while because of Matrix Calculation') 692 | img = MedFilterProc(l, img) 693 | 694 | # 创建toplevel窗口 695 | try: 696 | MedFilterWin.destroy() 697 | except Exception as e: 698 | print("NVM") 699 | finally: 700 | MedFilterWin = tkinter.Toplevel() 701 | MedFilterWin.attributes('-topmost', True) 702 | MedFilterWin.geometry("360x240") 703 | MedFilterWin.resizable(True,True) # 可缩放 704 | MedFilterWin.title("中值滤波") 705 | 706 | LabelPic = tkinter.Label(MedFilterWin, text="IMG", width=360, height=240) 707 | 708 | image = ImageTk.PhotoImage(Image.fromarray(img)) 709 | LabelPic.image = image 710 | LabelPic['image'] = image 711 | # cv2.imshow('image', image) 712 | def changeSize(event): 713 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 714 | LabelPic.image = image1 715 | LabelPic['image'] = image1 716 | LabelPic.bind('', changeSize) 717 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 718 | 719 | return 720 | 721 | ################################################################################################################################ 722 | 723 | # Sobel图像锐化 724 | def Sobel_Sharpening(): 725 | global Img_path, SobelSharpenWin 726 | print("Sobel锐化") 727 | if(Img_path==""): 728 | return 729 | 730 | # 得到img的array 731 | img=np.array(Image.open(Img_path)) 732 | # img = cv2.imread(Img_path) 733 | # img = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY) 734 | 735 | def Sobel_Sharpen(img): 736 | img = img.astype(np.int32) 737 | fx = np.ones(img.shape, np.int32) 738 | fy = np.ones(img.shape, np.int32) 739 | contemplateX = np.array([[-1,0,1],[-2,0,2],[-1,0,1]]) 740 | contemplateY = np.array([[-1,-2,-1],[0,0,0],[1,2,1]]) 741 | def HorizontalSobel(Img3DMatrix): 742 | # axis0为纵轴,1为深度轴,2为横轴,这很坑 743 | blank = 0 744 | if len(img.shape)==2: 745 | blank = np.sum(Img3DMatrix*contemplateX) 746 | else: 747 | blank = np.zeros((img.shape[2])) 748 | for i in range(img.shape[2]): 749 | blank[i] = np.sum(Img3DMatrix[:,:,i]*contemplateX) 750 | return blank 751 | 752 | def VerticalSobel(Img3DMatrix): 753 | # axis0为纵轴,1为深度轴,2为横轴,这很坑 754 | blank = 0 755 | if len(img.shape)==2: 756 | blank = np.sum(Img3DMatrix*contemplateY) 757 | else: 758 | blank = np.zeros((img.shape[2])) 759 | for i in range(img.shape[2]): 760 | blank[i] = np.sum(Img3DMatrix[:,:,i]*contemplateY) 761 | return blank 762 | 763 | # 计算填充数 764 | padding = 1 765 | # print('img', img.shape) 766 | if len(img.shape)==2: 767 | # 支持一维灰度图 768 | pad = ((padding, padding), (padding, padding)) 769 | else: 770 | # 长、高填充,深度不填充 771 | pad = ((padding, padding), (padding, padding), (0,0)) 772 | # 图片周围填充0 773 | padImg= np.pad(img, pad, 'constant', constant_values=(0, 0)) 774 | fx = np.pad(img, pad, 'constant', constant_values=(0, 0)) 775 | fy = np.pad(img, pad, 'constant', constant_values=(0, 0)) 776 | 777 | print('padImg', padImg.shape) 778 | # 高 1080 779 | for i in range(padding, padImg.shape[0] - padding): 780 | # 长 1920 781 | for j in range(padding, padImg.shape[1] - padding): 782 | # 求fx 783 | fx[i][j] = HorizontalSobel(padImg[i-padding:i+padding+1, j-padding:j+padding+1]) 784 | # 求fy 785 | fy[i][j] = VerticalSobel(padImg[i-padding:i+padding+1, j-padding:j+padding+1]) 786 | 787 | fx = fx[padding:padImg.shape[0] - padding, padding:padImg.shape[1] - padding] #把操作完多余的0去除,保证尺寸一样大 788 | fy = fy[padding:padImg.shape[0] - padding, padding:padImg.shape[1] - padding] #把操作完多余的0去除,保证尺寸一样大 789 | 790 | # 若是多通道,则每层分别计算 791 | if len(img.shape)==2: 792 | cv2.imshow('fx',np.uint8(fx)) 793 | cv2.imshow('fy',np.uint8(fy)) 794 | fx2 = fx*fx 795 | fy2 = fy*fy 796 | dst = np.sqrt(fx2 + fy2) 797 | else: 798 | dst = np.zeros(img.shape) 799 | for i in range(img.shape[2]): 800 | # cv2.imshow('fx'+str(i),np.uint8(fx[:,:,i])) 801 | # cv2.imshow('fy'+str(i),np.uint8(fy[:,:,i])) 802 | dst[:,:,i] = np.sqrt(fx[:,:,i]*fx[:,:,i] + fy[:,:,i]*fy[:,:,i]) 803 | 804 | 805 | dst[dst>255] = 255 806 | # 不加就会在Image.fromarray报错 807 | dst = dst.astype(np.uint8) 808 | return dst 809 | 810 | # 进行变换 811 | img = Sobel_Sharpen(img) 812 | 813 | # 创建toplevel窗口 814 | try: 815 | SobelSharpenWin.destroy() 816 | except Exception as e: 817 | print("NVM") 818 | finally: 819 | SobelSharpenWin = tkinter.Toplevel() 820 | SobelSharpenWin.attributes('-topmost', True) 821 | SobelSharpenWin.geometry("360x240") 822 | SobelSharpenWin.resizable(True,True) # 可缩放 823 | SobelSharpenWin.title("Sobel锐化") 824 | 825 | LabelPic = tkinter.Label(SobelSharpenWin, text="IMG", width=360, height=240) 826 | 827 | image = ImageTk.PhotoImage(Image.fromarray(img)) 828 | LabelPic.image = image 829 | LabelPic['image'] = image 830 | # cv2.imshow('image', image) 831 | def changeSize(event): 832 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(img, (event.width, event.height)))) 833 | LabelPic.image = image1 834 | LabelPic['image'] = image1 835 | LabelPic.bind('', changeSize) 836 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 837 | 838 | return 839 | 840 | ################################################################################################################################ 841 | 842 | # HOG人脸检测 843 | def HOGFaceRecognition(): 844 | global FaceRecogWinn 845 | print("HOG人脸检测") 846 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 847 | 848 | if not filePath: 849 | tkinter.messagebox.showerror(message="Cannot open this file!") 850 | return 851 | 852 | if (is_chinese(filePath)): 853 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 854 | return 855 | 856 | try: 857 | FaceRecogWinn.destroy() 858 | except Exception as e: 859 | print("NVM") 860 | finally: 861 | FaceRecogWinn = tkinter.Toplevel() 862 | FaceRecogWinn.attributes('-topmost', True) 863 | 864 | FaceRecogWinn.geometry("360x240") 865 | FaceRecogWinn.resizable(True,True) # 可缩放 866 | FaceRecogWinn.title("人脸检测") 867 | 868 | LabelPic = tkinter.Label(FaceRecogWinn, text="IMG", width=360, height=240) 869 | 870 | 871 | # 将jpg文件加载到numpy 数组中 872 | t=time.time() 873 | # 用于识别 874 | image = face_recognition.load_image_file(filePath) 875 | # 用于画框 876 | frame=cv2.imread(filePath) 877 | 878 | # 使用默认的给予HOG模型查找图像中所有人脸 879 | # 这个方法已经相当准确了,但还是不如CNN模型那么准确,因为没有使用GPU加速 880 | face_locations = face_recognition.face_locations(image) 881 | 882 | # 打印:我从图片中找到了 多少 张人脸 883 | print("I found {} face(s) in this photograph.".format(len(face_locations))) 884 | 885 | # 循环找到的所有人脸 886 | for face_location in face_locations: 887 | # 打印每张脸的位置信息 888 | top, right, bottom, left = face_location 889 | print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right)) 890 | # 指定人脸的位置信息,然后显示人脸图片 891 | cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) 892 | # cv2.imshow('tuxiang',frame) 893 | # cv2.waitKey(1) #刷新界面 不然只会呈现灰色 894 | print('运行时间{}'.format(time.time()-t)) 895 | 896 | frame = frame[:, :, ::-1] 897 | image = ImageTk.PhotoImage(Image.fromarray(frame)) 898 | LabelPic.image = image 899 | LabelPic['image'] = image 900 | # cv2.imshow('image', image) 901 | def changeSize(event): 902 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(frame, (event.width, event.height)))) 903 | LabelPic.image = image1 904 | LabelPic['image'] = image1 905 | LabelPic.bind('', changeSize) 906 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 907 | 908 | return 909 | 910 | # CNN人脸检测 911 | def CNNFaceRecognition(): 912 | global FaceRecogWinn 913 | print("CNN人脸检测") 914 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 915 | 916 | if not filePath: 917 | tkinter.messagebox.showerror(message="Cannot open this file!") 918 | return 919 | 920 | if (is_chinese(filePath)): 921 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 922 | return 923 | 924 | try: 925 | FaceRecogWinn.destroy() 926 | except Exception as e: 927 | print("NVM") 928 | finally: 929 | FaceRecogWinn = tkinter.Toplevel() 930 | FaceRecogWinn.attributes('-topmost', True) 931 | 932 | FaceRecogWinn.geometry("360x240") 933 | FaceRecogWinn.resizable(True,True) # 可缩放 934 | FaceRecogWinn.title("人脸检测") 935 | 936 | LabelPic = tkinter.Label(FaceRecogWinn, text="IMG", width=360, height=240) 937 | 938 | 939 | 940 | # 将jpg文件加载到numpy 数组中 941 | t=time.time() 942 | # 用于识别 943 | image = face_recognition.load_image_file(filePath) 944 | # 用于画框 945 | frame=cv2.imread(filePath) 946 | 947 | # 使用CNN模型 948 | face_locations = face_recognition.face_locations(image, number_of_times_to_upsample=0, model="cnn") 949 | 950 | # 打印:我从图片中找到了 多少 张人脸 951 | print("I found {} face(s) in this photograph.".format(len(face_locations))) 952 | 953 | # 循环找到的所有人脸 954 | for face_location in face_locations: 955 | # 打印每张脸的位置信息 956 | top, right, bottom, left = face_location 957 | print("A face is located at pixel location Top: {}, Left: {}, Bottom: {}, Right: {}".format(top, left, bottom, right)) 958 | # 指定人脸的位置信息,然后显示人脸图片 959 | cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2) 960 | 961 | print('运行时间{}'.format(time.time()-t)) 962 | 963 | frame = frame[:, :, ::-1] 964 | image = ImageTk.PhotoImage(Image.fromarray(frame)) 965 | LabelPic.image = image 966 | LabelPic['image'] = image 967 | # cv2.imshow('image', image) 968 | def changeSize(event): 969 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(frame, (event.width, event.height)))) 970 | LabelPic.image = image1 971 | LabelPic['image'] = image1 972 | LabelPic.bind('', changeSize) 973 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 974 | 975 | return 976 | 977 | # 虹软SDK人脸识别 978 | def ArcSoft(): 979 | global FaceRecogWinn 980 | print("\n虹软SDK人脸检测") 981 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 982 | 983 | if not filePath: 984 | tkinter.messagebox.showerror(message="Cannot open this file!") 985 | return 986 | 987 | if (is_chinese(filePath)): 988 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 989 | return 990 | 991 | try: 992 | FaceRecogWinn.destroy() 993 | except Exception as e: 994 | print("NVM") 995 | finally: 996 | FaceRecogWinn = tkinter.Toplevel() 997 | FaceRecogWinn.attributes('-topmost', True) 998 | 999 | FaceRecogWinn.geometry("360x240") 1000 | FaceRecogWinn.resizable(True,True) # 可缩放 1001 | FaceRecogWinn.title("虹软SDK") 1002 | 1003 | LabelPic = tkinter.Label(FaceRecogWinn, text="IMG", width=360, height=240) 1004 | 1005 | frame = detection(filePath) 1006 | frame = frame[:, :, ::-1] 1007 | image = ImageTk.PhotoImage(Image.fromarray(frame)) 1008 | LabelPic.image = image 1009 | LabelPic['image'] = image 1010 | # cv2.imshow('image', image) 1011 | def changeSize(event): 1012 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(frame, (event.width, event.height)))) 1013 | LabelPic.image = image1 1014 | LabelPic['image'] = image1 1015 | LabelPic.bind('', changeSize) 1016 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 1017 | 1018 | return 1019 | 1020 | # face++人脸识别SDK 1021 | def FacePPSDK(): 1022 | global FaceRecogWinn 1023 | print("\nface++SDK人脸检测") 1024 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 1025 | 1026 | if not filePath: 1027 | tkinter.messagebox.showerror(message="Cannot open this file!") 1028 | return 1029 | 1030 | if (is_chinese(filePath)): 1031 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 1032 | return 1033 | 1034 | try: 1035 | FaceRecogWinn.destroy() 1036 | except Exception as e: 1037 | print("NVM") 1038 | finally: 1039 | FaceRecogWinn = tkinter.Toplevel() 1040 | FaceRecogWinn.attributes('-topmost', True) 1041 | 1042 | FaceRecogWinn.geometry("360x240") 1043 | FaceRecogWinn.resizable(True,True) # 可缩放 1044 | FaceRecogWinn.title("Face++SDK") 1045 | 1046 | LabelPic = tkinter.Label(FaceRecogWinn, text="IMG", width=360, height=240) 1047 | 1048 | frame = Facepp(filePath) 1049 | frame = frame[:, :, ::-1] 1050 | image = ImageTk.PhotoImage(Image.fromarray(frame)) 1051 | LabelPic.image = image 1052 | LabelPic['image'] = image 1053 | 1054 | def changeSize(event): 1055 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(frame, (event.width, event.height)))) 1056 | LabelPic.image = image1 1057 | LabelPic['image'] = image1 1058 | LabelPic.bind('', changeSize) 1059 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 1060 | 1061 | return 1062 | 1063 | # paddlehub的PyramidBox_Lite模型 1064 | def paddleHub1(): 1065 | global FaceRecogWinn 1066 | print("\nPyramidBox_Lite人脸检测") 1067 | filePath = filedialog.askopenfilename(filetypes=[("PNG",".png"),("GPF",".gpf"),("JPG",".jpg"),("BMP",".bmp")]) # 打开文件夹对话框 1068 | 1069 | if not filePath: 1070 | tkinter.messagebox.showerror(message="Cannot open this file!") 1071 | return 1072 | 1073 | if (is_chinese(filePath)): 1074 | tkinter.messagebox.showerror(message="Cannot open this file because of Chinese Path!") 1075 | return 1076 | 1077 | try: 1078 | FaceRecogWinn.destroy() 1079 | except Exception as e: 1080 | print("NVM") 1081 | finally: 1082 | FaceRecogWinn = tkinter.Toplevel() 1083 | FaceRecogWinn.attributes('-topmost', True) 1084 | 1085 | FaceRecogWinn.geometry("360x240") 1086 | FaceRecogWinn.resizable(True,True) # 可缩放 1087 | FaceRecogWinn.title("PyramidBox_Lite") 1088 | 1089 | LabelPic = tkinter.Label(FaceRecogWinn, text="IMG", width=360, height=240) 1090 | 1091 | frame = paddlePyramidBox_Lite(filePath) 1092 | frame = frame[:, :, ::-1] 1093 | image = ImageTk.PhotoImage(Image.fromarray(frame)) 1094 | LabelPic.image = image 1095 | LabelPic['image'] = image 1096 | 1097 | def changeSize(event): 1098 | image1 = ImageTk.PhotoImage(Image.fromarray(cv2.resize(frame, (event.width, event.height)))) 1099 | LabelPic.image = image1 1100 | LabelPic['image'] = image1 1101 | LabelPic.bind('', changeSize) 1102 | LabelPic.pack(fill=tkinter.BOTH, expand=tkinter.YES) 1103 | 1104 | return 1105 | 1106 | 1107 | 1108 | 1109 | 1110 | #################################################################################################################################### 1111 | #################################################################################################################################### 1112 | ###################################### HELP CLASS ######################################### 1113 | #################################################################################################################################### 1114 | #################################################################################################################################### 1115 | 1116 | 1117 | class HELP: 1118 | ''' 1119 | 帮助 1120 | ['检查更新', '关于作者'] 1121 | ''' 1122 | def Update(): 1123 | res = tkinter.messagebox.showinfo(title='版本信息', message='\n更新日期: 2020/06/22\n软件版本: V1.0\n版权所有: 钟路迦') 1124 | print(res) 1125 | return 1126 | 1127 | def ABOUT(): 1128 | res = tkinter.messagebox.showinfo(title='作者信息', 1129 | message='\n开发人员: 钟路迦\n所在单位: CAU CIEE CS 172\n联系电话: *******2219\n邮箱: zljdanceholic@cau.edu.cn\nQQ: 93737****\n') 1130 | print(res) 1131 | return -------------------------------------------------------------------------------- /processing/__init__.py: -------------------------------------------------------------------------------- 1 | from processing import ImgProcessing -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | # pip install -r requirements.txt 2 | 3 | # base ---------------------------------------- 4 | opencv-python>=4.2.0.34 5 | json5>=0.9.4 6 | jsonschema>=3.0.1 7 | requests>=2.21.0 8 | matplotlib>=3.1.1 9 | numpy>=1.16.2 10 | Pillow>=7.1.2 11 | pyglet>=1.5.6 12 | 13 | 14 | # face detection related ---------------------- 15 | face_recognition>=1.3.0 16 | paddlehub>=1.7.1 17 | -------------------------------------------------------------------------------- /screenshots/Logarithmic_gray_scale_transformation.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/Logarithmic_gray_scale_transformation.png -------------------------------------------------------------------------------- /screenshots/Login.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/Login.png -------------------------------------------------------------------------------- /screenshots/RGB_histogram.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/RGB_histogram.png -------------------------------------------------------------------------------- /screenshots/Sobel.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/Sobel.png -------------------------------------------------------------------------------- /screenshots/img_add.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/img_add.png -------------------------------------------------------------------------------- /screenshots/median_filtering.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/median_filtering.png -------------------------------------------------------------------------------- /screenshots/modifications.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/modifications.png -------------------------------------------------------------------------------- /screenshots/n_value.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/n_value.png -------------------------------------------------------------------------------- /screenshots/register.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/screenshots/register.png -------------------------------------------------------------------------------- /usrs_info.pickle: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/lujiazho/Digital-Image-Processing/079f768b39986245b56e81ce340a2db23ce27356/usrs_info.pickle --------------------------------------------------------------------------------