parent
3594bb1c18
commit
5229230b95
@ -0,0 +1,2 @@
|
||||
# Default ignored files
|
||||
/workspace.xml
|
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="JavaScriptSettings">
|
||||
<option name="languageLevel" value="ES6" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.7 (Digital_Image_Process-master)" project-jdk-type="Python SDK" />
|
||||
</project>
|
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/resource.iml" filepath="$PROJECT_DIR$/.idea/resource.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
@ -0,0 +1,13 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.7 (Digital_Image_Process-master)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="TestRunnerService">
|
||||
<option name="PROJECT_TEST_RUNNER" value="Unittests" />
|
||||
</component>
|
||||
</module>
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,35 @@
|
||||
from custom.tableWidget import *
|
||||
from custom.listWidgetItems import *
|
||||
|
||||
|
||||
# Implemented functions
|
||||
items = [
|
||||
GeometricTransItem,
|
||||
GrayingItem,
|
||||
EqualizeItem,
|
||||
FilterItem,
|
||||
SharpenItem,
|
||||
AddNoiseItem,
|
||||
FrequencyFilterItem,
|
||||
SelectFilterItem,
|
||||
ColorImageProcessItem,
|
||||
AffineItem,
|
||||
BeautyItem,
|
||||
IdCardPicGenerateItem,
|
||||
]
|
||||
|
||||
tables = [
|
||||
GeometricTransTableWight,
|
||||
GrayingTableWidget,
|
||||
EqualizeTableWidget,
|
||||
FilterTabledWidget,
|
||||
SharpenItemTableWidget,
|
||||
AddNoiseItemTableWidget,
|
||||
FrequencyFilterTabledWidget,
|
||||
SelectFilterTabledWidget,
|
||||
ColorImageProcessTabledWidget,
|
||||
LineTableWidget,
|
||||
BeautyTableWight,
|
||||
IdCardPicGenerateTabledWidget,
|
||||
]
|
||||
|
@ -0,0 +1,15 @@
|
||||
from cv2 import selectROI,imwrite
|
||||
from PyQt5.QtWidgets import QMainWindow, QFileDialog
|
||||
|
||||
|
||||
class childwindow1(QMainWindow):
|
||||
def __init__(self,parent=None):
|
||||
super(childwindow1, self).__init__(parent)
|
||||
def openfile(self):
|
||||
fname, _ = QFileDialog.getOpenFileName(self, 'Open file', '.', 'Image Files(*.jpg *.bmp *.png *.jpeg *.rgb *.tif)')
|
||||
return fname
|
||||
def selectROI(self,img):
|
||||
bbox = selectROI(img, False)
|
||||
cut = img[bbox[1]:bbox[1] + bbox[3], bbox[0]:bbox[0] + bbox[2]]
|
||||
imwrite('cut.jpg', cut)
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,78 @@
|
||||
from PyQt5.QtCore import Qt, QRectF
|
||||
from PyQt5.QtGui import QCursor, QImage, QPixmap
|
||||
from PyQt5.QtWidgets import QGraphicsView, QGraphicsPixmapItem, QGraphicsScene, QMenu, QAction, QFileDialog
|
||||
from cv2 import cvtColor,COLOR_BGR2RGB
|
||||
|
||||
class GraphicsView(QGraphicsView):
|
||||
def __init__(self, parent=None):
|
||||
super(GraphicsView, self).__init__(parent=parent)
|
||||
self._zoom = 0
|
||||
self._empty = True
|
||||
self._photo = QGraphicsPixmapItem()
|
||||
self._scene = QGraphicsScene(self)
|
||||
self._scene.addItem(self._photo)
|
||||
|
||||
|
||||
self.setScene(self._scene)
|
||||
# self.setScene(self._scene1)
|
||||
self.setAlignment(Qt.AlignCenter) # 居中显示
|
||||
self.setDragMode(QGraphicsView.ScrollHandDrag) # 设置拖动
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
self.setMinimumSize(640, 480)
|
||||
|
||||
def contextMenuEvent(self, event):
|
||||
if not self.has_photo():
|
||||
return
|
||||
menu = QMenu()
|
||||
save_action = QAction('另存为', self)
|
||||
save_action.triggered.connect(self.save_current) # 传递额外值
|
||||
menu.addAction(save_action)
|
||||
menu.exec(QCursor.pos())
|
||||
|
||||
def save_current(self):
|
||||
file_name = QFileDialog.getSaveFileName(self, '另存为', './', 'Image files(*.jpg *.gif *.png)')[0]
|
||||
print(file_name)
|
||||
if file_name:
|
||||
self._photo.pixmap().save(file_name)
|
||||
|
||||
def get_image(self):
|
||||
if self.has_photo():
|
||||
return self._photo.pixmap().toImage()
|
||||
|
||||
def has_photo(self):
|
||||
return not self._empty
|
||||
|
||||
def change_image(self, img):
|
||||
self.update_image(img)
|
||||
self.fitInView()
|
||||
|
||||
def img_to_pixmap(self, img):
|
||||
img = cvtColor(img, COLOR_BGR2RGB) # bgr -> rgb
|
||||
h, w, c = img.shape # 获取图片形状
|
||||
image = QImage(img, w, h, 3 * w, QImage.Format_RGB888)
|
||||
return QPixmap.fromImage(image)
|
||||
|
||||
def update_image(self, img):
|
||||
self._empty = False
|
||||
self._photo.setPixmap(self.img_to_pixmap(img))
|
||||
|
||||
def fitInView(self, scale=True):
|
||||
rect = QRectF(self._photo.pixmap().rect())
|
||||
if not rect.isNull():
|
||||
self.setSceneRect(rect)
|
||||
|
||||
def wheelEvent(self, event):
|
||||
if self.has_photo():
|
||||
if event.angleDelta().y() > 0:
|
||||
factor = 1.25
|
||||
self._zoom += 1
|
||||
else:
|
||||
factor = 0.8
|
||||
self._zoom -= 1
|
||||
if self._zoom > 0:
|
||||
self.scale(factor, factor)
|
||||
elif self._zoom == 0:
|
||||
self.fitInView()
|
||||
else:
|
||||
self._zoom = 0
|
@ -0,0 +1,86 @@
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtGui import QCursor
|
||||
from PyQt5.QtWidgets import QListWidget, QListView, QAbstractItemView, QAction, QMenu
|
||||
|
||||
from config import items
|
||||
|
||||
|
||||
class MyListWidget(QListWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.mainwindow = parent
|
||||
self.setDragEnabled(True)
|
||||
# 选中不显示虚线
|
||||
# self.setEditTriggers(QAbstractItemView.NoEditTriggers)
|
||||
self.setFocusPolicy(Qt.NoFocus)
|
||||
|
||||
|
||||
class UsedListWidget(MyListWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setAcceptDrops(True) # 激活组件的拖拽事件
|
||||
self.setFlow(QListView.TopToBottom) # 设置列表方向(表示数据项从上至下排列)
|
||||
self.setDefaultDropAction(Qt.MoveAction) # 设置拖放为移动而不是复制一个
|
||||
self.setDragDropMode(QAbstractItemView.InternalMove) # 设置拖放模式, 内部拖放
|
||||
self.itemClicked.connect(self.show_attr)
|
||||
self.setMinimumWidth(200)
|
||||
|
||||
self.move_item = None
|
||||
|
||||
def contextMenuEvent(self, e):
|
||||
# 右键菜单事件
|
||||
item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
|
||||
if not item: return # 判断是否是空白区域
|
||||
menu = QMenu()
|
||||
delete_action = QAction('删除', self)
|
||||
delete_action.triggered.connect(lambda: self.delete_item(item)) # 传递额外值
|
||||
menu.addAction(delete_action)
|
||||
menu.exec(QCursor.pos())
|
||||
|
||||
def delete_item(self, item):
|
||||
# 删除操作
|
||||
self.takeItem(self.row(item))
|
||||
self.mainwindow.update_image() # 更新frame
|
||||
self.mainwindow.dock_attr.close()
|
||||
|
||||
def dropEvent(self, event):
|
||||
super().dropEvent(event)
|
||||
self.mainwindow.update_image()
|
||||
|
||||
def show_attr(self):
|
||||
item = self.itemAt(self.mapFromGlobal(QCursor.pos()))
|
||||
if not item: return
|
||||
param = item.get_params() # 获取当前item的属性
|
||||
if type(item) in items:
|
||||
index = items.index(type(item)) # 获取item对应的table索引
|
||||
self.mainwindow.stackedWidget.setCurrentIndex(index)
|
||||
self.mainwindow.stackedWidget.currentWidget().update_params(param) # 更新对应的table
|
||||
self.mainwindow.dock_attr.show()
|
||||
|
||||
|
||||
class FuncListWidget(MyListWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.setFixedHeight(64)
|
||||
self.setFlow(QListView.LeftToRight) # 设置列表方向
|
||||
self.setViewMode(QListView.IconMode) # 设置列表模式
|
||||
# self.setViewMode(QListView.ViewMode)
|
||||
self.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff) # 关掉滑动条
|
||||
self.setAcceptDrops(False)
|
||||
for itemType in items:
|
||||
self.addItem(itemType())
|
||||
self.itemClicked.connect(self.add_used_function)
|
||||
|
||||
def add_used_function(self):
|
||||
func_item = self.currentItem()
|
||||
if type(func_item) in items:
|
||||
use_item = type(func_item)()
|
||||
self.mainwindow.useListWidget.addItem(use_item)
|
||||
self.mainwindow.update_image()
|
||||
|
||||
def enterEvent(self, event):
|
||||
self.setCursor(Qt.PointingHandCursor)
|
||||
|
||||
def leaveEvent(self, event):
|
||||
self.setCursor(Qt.ArrowCursor)
|
||||
self.setCurrentRow(-1) # 取消选中状态
|
@ -0,0 +1,11 @@
|
||||
from PyQt5.QtWidgets import QStackedWidget
|
||||
|
||||
from config import tables
|
||||
|
||||
|
||||
class StackedWidget(QStackedWidget):
|
||||
def __init__(self, parent):
|
||||
super().__init__(parent=parent)
|
||||
for table in tables:
|
||||
self.addWidget(table(parent=parent))
|
||||
self.setMinimumWidth(200)
|
@ -0,0 +1,33 @@
|
||||
from cv2 import imdecode
|
||||
import numpy as np
|
||||
from PyQt5.QtCore import Qt
|
||||
from PyQt5.QtWidgets import QTreeView, QDockWidget, QFileSystemModel
|
||||
|
||||
|
||||
class FileSystemTreeView(QTreeView, QDockWidget):
|
||||
def __init__(self, parent=None):
|
||||
super().__init__(parent=parent)
|
||||
self.mainwindow = parent
|
||||
self.fileSystemModel = QFileSystemModel()
|
||||
self.fileSystemModel.setRootPath('.')
|
||||
self.setModel(self.fileSystemModel)
|
||||
# 隐藏size,date等列
|
||||
self.setColumnWidth(0, 200)
|
||||
self.setColumnHidden(1, True)
|
||||
self.setColumnHidden(2, True)
|
||||
self.setColumnHidden(3, True)
|
||||
# 不显示标题栏
|
||||
self.header().hide()
|
||||
# 设置动画
|
||||
self.setAnimated(True)
|
||||
# 选中不显示虚线
|
||||
self.setFocusPolicy(Qt.NoFocus)
|
||||
self.doubleClicked.connect(self.select_image)
|
||||
self.setMinimumWidth(200)
|
||||
|
||||
def select_image(self, file_index):
|
||||
file_name = self.fileSystemModel.filePath(file_index)
|
||||
if file_name.endswith(('.jpg', '.png', '.bmp')):
|
||||
src_img = imdecode(np.fromfile(file_name, dtype=np.uint8), -1)
|
||||
self.mainwindow.change_image(src_img)
|
||||
|
Binary file not shown.
@ -0,0 +1,125 @@
|
||||
import cv2
|
||||
|
||||
GRAYING_STACKED_WIDGET = 0
|
||||
FILTER_STACKED_WIDGET = 1
|
||||
MORPH_STACKED_WIDGET = 2
|
||||
GRAD_STACKED_WIDGET = 3
|
||||
THRESH_STACKED_WIDGET = 4
|
||||
EDGE_STACKED_WIDGET = 5
|
||||
|
||||
# 功能区
|
||||
|
||||
BGR2GRAY_COLOR = 0
|
||||
GRAY2BGR_COLOR = 1
|
||||
COLOR = {
|
||||
BGR2GRAY_COLOR: cv2.COLOR_BGR2GRAY,
|
||||
GRAY2BGR_COLOR: cv2.COLOR_GRAY2BGR
|
||||
}
|
||||
|
||||
# 图像灰度处理
|
||||
RBG2GRAY = 0
|
||||
REVERSE = 1
|
||||
PLTRANS = 2
|
||||
Binarization = 3
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
MEAN_FILTER = 0
|
||||
GAUSSIAN_FILTER = 1
|
||||
MEDIAN_FILTER = 2
|
||||
|
||||
ERODE_MORPH_OP = 0
|
||||
DILATE_MORPH_OP = 1
|
||||
OPEN_MORPH_OP = 2
|
||||
CLOSE_MORPH_OP = 3
|
||||
GRADIENT_MORPH_OP = 4
|
||||
TOPHAT_MORPH_OP = 5
|
||||
BLACKHAT_MORPH_OP = 6
|
||||
|
||||
MORPH_OP = {
|
||||
ERODE_MORPH_OP: cv2.MORPH_ERODE,
|
||||
DILATE_MORPH_OP: cv2.MORPH_DILATE,
|
||||
OPEN_MORPH_OP: cv2.MORPH_OPEN,
|
||||
CLOSE_MORPH_OP: cv2.MORPH_CLOSE,
|
||||
GRADIENT_MORPH_OP: cv2.MORPH_GRADIENT,
|
||||
TOPHAT_MORPH_OP: cv2.MORPH_TOPHAT,
|
||||
BLACKHAT_MORPH_OP: cv2.MORPH_BLACKHAT
|
||||
}
|
||||
|
||||
RECT_MORPH_SHAPE = 0
|
||||
CROSS_MORPH_SHAPE = 1
|
||||
ELLIPSE_MORPH_SHAPE = 2
|
||||
|
||||
MORPH_SHAPE = {
|
||||
RECT_MORPH_SHAPE: cv2.MORPH_RECT,
|
||||
CROSS_MORPH_SHAPE: cv2.MORPH_CROSS,
|
||||
ELLIPSE_MORPH_SHAPE: cv2.MORPH_ELLIPSE
|
||||
}
|
||||
|
||||
SOBEL_GRAD = 0
|
||||
SCHARR_GRAD = 1
|
||||
LAPLACIAN_GRAD = 2
|
||||
|
||||
BINARY_THRESH_METHOD = 0
|
||||
BINARY_INV_THRESH_METHOD = 1
|
||||
TRUNC_THRESH_METHOD = 2
|
||||
TOZERO_THRESH_METHOD = 3
|
||||
TOZERO_INV_THRESH_METHOD = 4
|
||||
OTSU_THRESH_METHOD = 5
|
||||
THRESH_METHOD = {
|
||||
BINARY_THRESH_METHOD: cv2.THRESH_BINARY, # 0
|
||||
BINARY_INV_THRESH_METHOD: cv2.THRESH_BINARY_INV, # 1
|
||||
TRUNC_THRESH_METHOD: cv2.THRESH_TRUNC, # 2
|
||||
TOZERO_THRESH_METHOD: cv2.THRESH_TOZERO, # 3
|
||||
TOZERO_INV_THRESH_METHOD: cv2.THRESH_TOZERO_INV, # 4
|
||||
OTSU_THRESH_METHOD: cv2.THRESH_OTSU # 5
|
||||
}
|
||||
|
||||
EXTERNAL_CONTOUR_MODE = 0
|
||||
LIST_CONTOUR_MODE = 1
|
||||
CCOMP_CONTOUR_MODE = 2
|
||||
TREE_CONTOUR_MODE = 3
|
||||
CONTOUR_MODE = {
|
||||
EXTERNAL_CONTOUR_MODE: cv2.RETR_EXTERNAL,
|
||||
LIST_CONTOUR_MODE: cv2.RETR_LIST,
|
||||
CCOMP_CONTOUR_MODE: cv2.RETR_CCOMP,
|
||||
TREE_CONTOUR_MODE: cv2.RETR_TREE
|
||||
}
|
||||
|
||||
NONE_CONTOUR_METHOD = 0
|
||||
SIMPLE_CONTOUR_METHOD = 1
|
||||
CONTOUR_METHOD = {
|
||||
NONE_CONTOUR_METHOD: cv2.CHAIN_APPROX_NONE,
|
||||
SIMPLE_CONTOUR_METHOD: cv2.CHAIN_APPROX_SIMPLE
|
||||
}
|
||||
|
||||
NORMAL_CONTOUR = 0
|
||||
RECT_CONTOUR = 1
|
||||
MINRECT_CONTOUR = 2
|
||||
MINCIRCLE_CONTOUR = 3
|
||||
|
||||
|
||||
# 均衡化
|
||||
BLUE_CHANNEL = 0
|
||||
GREEN_CHANNEL = 1
|
||||
RED_CHANNEL = 2
|
||||
ALL_CHANNEL = 3
|
||||
|
||||
|
||||
# 伪彩色变换
|
||||
COLORMAP_AUTUMN = 0
|
||||
COLORMAP_BONE = 1
|
||||
COLORMAP_JET = 2
|
||||
COLORMAP_WINTER = 3
|
||||
COLORMAP_RAINBOW = 4
|
||||
COLORMAP_OCEAN = 5
|
||||
COLORMAP_SUMMER = 6
|
||||
COLORMAP_SPRING = 7
|
||||
COLORMAP_COOL = 8
|
||||
COLORMAP_HSV = 9
|
||||
COLORMAP_PINK = 10
|
||||
COLORMAP_HOT = 11
|
@ -0,0 +1,15 @@
|
||||
# import numpy as np
|
||||
from numpy import array,random,clip,uint8
|
||||
|
||||
def exponential_noise(image, scale = 0.1):
|
||||
|
||||
image = array(image/255, dtype=float)
|
||||
noise = random.exponential(scale,image.shape)
|
||||
out = image + noise
|
||||
if out.min() < 0:
|
||||
low_clip = -1.
|
||||
else:
|
||||
low_clip = 0.
|
||||
out = clip(out, low_clip, 1.0)
|
||||
out = uint8(out*255)
|
||||
return out
|
@ -0,0 +1,17 @@
|
||||
# import numpy as np
|
||||
# import cv2
|
||||
from numpy import array,random,clip,uint8
|
||||
|
||||
def gamma_noise(image, var=0.1):
|
||||
|
||||
image = array(image/255, dtype=float)
|
||||
# 伽马分布
|
||||
noise = random.gamma(3,var ** 0.5, image.shape)
|
||||
out = image + noise
|
||||
if out.min() < 0:
|
||||
low_clip = -1.
|
||||
else:
|
||||
low_clip = 0.
|
||||
out = clip(out, low_clip, 1.0)
|
||||
out = uint8(out*255)
|
||||
return out
|
@ -0,0 +1,17 @@
|
||||
# import numpy as np
|
||||
# import cv2
|
||||
from numpy import array,random,clip,uint8
|
||||
|
||||
def gasuss_noise(image, var=0.1, mean=0):
|
||||
|
||||
image = array(image/255, dtype=float)
|
||||
# 高斯分布
|
||||
noise = random.normal(mean, var ** 0.5, image.shape)
|
||||
out = image + noise
|
||||
if out.min() < 0:
|
||||
low_clip = -1.
|
||||
else:
|
||||
low_clip = 0.
|
||||
out = clip(out, low_clip, 1.0)
|
||||
out = uint8(out*255)
|
||||
return out
|
@ -0,0 +1,19 @@
|
||||
from random import random
|
||||
from numpy import zeros,uint8,random
|
||||
import cv2
|
||||
|
||||
def impluse_noise(image,prob=0.1):
|
||||
|
||||
output = zeros(image.shape,uint8)
|
||||
thres = 1 - prob
|
||||
for i in range(image.shape[0]):
|
||||
for j in range(image.shape[1]):
|
||||
rdn = random.random()
|
||||
if rdn < prob:
|
||||
output[i][j] = 0
|
||||
elif rdn > thres:
|
||||
output[i][j] = 255
|
||||
else:
|
||||
output[i][j] = image[i][j]
|
||||
return output
|
||||
|
@ -0,0 +1,16 @@
|
||||
# import numpy as np
|
||||
from numpy import array,clip,uint8
|
||||
from numpy.random import rayleigh
|
||||
def rayleigh_noise(image,var=0.1):
|
||||
|
||||
image = array(image/255, dtype=float)
|
||||
# 瑞利分布
|
||||
noise = rayleigh(var ** 0.5, image.shape)
|
||||
out = image + noise
|
||||
if out.min() < 0:
|
||||
low_clip = -1.
|
||||
else:
|
||||
low_clip = 0.
|
||||
out = clip(out, low_clip, 1.0)
|
||||
out = uint8(out*255)
|
||||
return out
|
@ -0,0 +1,15 @@
|
||||
from numpy import array,clip,uint8
|
||||
from numpy.random import uniform
|
||||
def uniform_noise(image,hight=1.0,low=0.0):
|
||||
|
||||
image = array(image/255, dtype=float)
|
||||
# 均匀分布
|
||||
noise = uniform(low,hight,image.shape)
|
||||
out = image + noise
|
||||
if out.min() < 0:
|
||||
low_clip = -1.
|
||||
else:
|
||||
low_clip = 0.
|
||||
out = clip(out, low_clip, 1.0)
|
||||
out = uint8(out*255)
|
||||
return out
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,27 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
def Beauty(img):
|
||||
step = 5
|
||||
kernel = (32,32) #图片大一点,此处尺寸大一点
|
||||
|
||||
img = img/255.0
|
||||
sz = img.shape[:2]
|
||||
sz1 = (int(round(sz[1] * step)), int(round(sz[0] * step)))
|
||||
sz2 = (int(round(kernel[0] * step)), int(round(kernel[0] * step)))
|
||||
sI = cv2.resize(img, sz1, interpolation=cv2.INTER_LINEAR)
|
||||
sp = cv2.resize(img, sz1, interpolation=cv2.INTER_LINEAR)
|
||||
msI = cv2.blur(sI, sz2)
|
||||
msp = cv2.blur(sp, sz2)
|
||||
msII = cv2.blur(sI*sI, sz2)
|
||||
msIp = cv2.blur(sI*sp, sz2)
|
||||
vsI = msII - msI*msI
|
||||
csIp = msIp - msI*msp
|
||||
recA = csIp/(vsI+0.01)
|
||||
recB = msp - recA*msI
|
||||
mA = cv2.resize(recA, (sz[1],sz[0]), interpolation=cv2.INTER_LINEAR)
|
||||
mB = cv2.resize(recB, (sz[1],sz[0]), interpolation=cv2.INTER_LINEAR)
|
||||
gf = mA*img + mB
|
||||
gf = gf*255
|
||||
gf[gf>255] = 255
|
||||
final = gf.astype(np.uint8)
|
||||
return final
|
Binary file not shown.
Binary file not shown.
@ -0,0 +1,46 @@
|
||||
import cv2
|
||||
|
||||
from function.GrayscaleTrans.BGR2GRAY import rgbToGray
|
||||
from function.ColorImageProcess.HSIProcess import hsvProcess
|
||||
|
||||
|
||||
def pseudoColorTrans(img,H,S,V,type):
|
||||
if img.shape == 4:
|
||||
img = cv2.cvtColor(img,cv2.COLOR_RGBA2BGR)
|
||||
img_gray = rgbToGray(img)
|
||||
if type == 0:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_AUTUMN)
|
||||
elif type == 1:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_BONE)
|
||||
elif type == 2:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_JET)
|
||||
elif type == 3:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_WINTER)
|
||||
elif type == 4:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_RAINBOW)
|
||||
elif type == 5:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_OCEAN)
|
||||
elif type == 6:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_SUMMER)
|
||||
elif type == 7:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_SPRING)
|
||||
elif type == 8:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_COOL)
|
||||
elif type == 9:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_HSV)
|
||||
elif type == 10:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_PINK)
|
||||
elif type == 11:
|
||||
img_color = cv2.applyColorMap(img_gray, cv2.COLORMAP_HOT)
|
||||
img_color = hsvProcess(img_color,H,S,V)
|
||||
return img_color
|
||||
|
||||
|
||||
# img_gray = cv2.imread("../pic/beach.png",cv2.IMREAD_GRAYSCALE)
|
||||
# img_color = cv2.applyColorMap(img_gray,cv2.COLORMAP_JET)
|
||||
# img = cv2.imread('../pic/beach.png')
|
||||
# img_gray = pseudoColorTrans(img,type)
|
||||
# cv2.imshow('img_color',img_gray)
|
||||
# cv2.waitKey(0)
|
||||
# cv2.imshow('img_color',img_color)
|
||||
# cv2.waitKey(0)
|
@ -0,0 +1,16 @@
|
||||
import cv2
|
||||
from function.ColorImageProcess.HSIProcess import hsvProcess
|
||||
|
||||
|
||||
def rgb2cmy(img,H,S,V):
|
||||
if img.shape[2] == 4:
|
||||
img = cv2.cvtColor(img,cv2.COLOR_RGBA2RGB)
|
||||
(b,g,r) = cv2.split(img)
|
||||
b = 1 - b/b.max()
|
||||
g = 1 - g/g.max()
|
||||
r = 1 - r/r.max()
|
||||
img_1 = cv2.merge([255*b,255*g,255*r])
|
||||
img_result = hsvProcess(img_1,H,S,V)
|
||||
return img_result
|
||||
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,75 @@
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from function.GrayscaleTrans.BGR2GRAY import rgbToGray
|
||||
|
||||
|
||||
def make_transform_matrix(image,d,s1,n):
|
||||
transfor_matrix = np.zeros(image.shape)
|
||||
center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
|
||||
for i in range(transfor_matrix.shape[0]):
|
||||
for j in range(transfor_matrix.shape[1]):
|
||||
def cal_distance(pa, pb):
|
||||
from math import sqrt
|
||||
dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
|
||||
return dis
|
||||
|
||||
dis = cal_distance(center_point, (i, j))
|
||||
transfor_matrix[i, j] = 1 / ((1 + (dis / d)) ** (2 * n))
|
||||
return transfor_matrix
|
||||
|
||||
|
||||
def butterworthFilter(image, d, n,kind):
|
||||
'''
|
||||
巴特沃斯低通滤波器
|
||||
:param image: 输入图像
|
||||
:param d: 滤波半径
|
||||
:param n: 阶数
|
||||
:return:
|
||||
'''
|
||||
image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
|
||||
image = rgbToGray(image)
|
||||
f = np.fft.fft2(image)
|
||||
fshift = np.fft.fftshift(f)
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 1:
|
||||
d_matrix = make_transform_matrix(image,d,s1,n)
|
||||
elif kind == 4:
|
||||
d_matrix = 1-make_transform_matrix(image, d, s1, n)
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
|
||||
# 高通滤波
|
||||
# img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * (1-d_matrix))))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
||||
|
||||
|
||||
# 定义函数,巴特沃斯带阻/通滤波模板
|
||||
def ButterworthBand(src, w, d0, n):
|
||||
template = np.zeros(src.shape, dtype=np.float32) # 构建滤波器
|
||||
r, c = src.shape
|
||||
for i in np.arange(r):
|
||||
for j in np.arange(c):
|
||||
distance = np.sqrt((i - r / 2) ** 2 + (j - c / 2) ** 2)
|
||||
# 巴特沃斯分布
|
||||
template[i, j] = 1/(1+(distance*w/(distance**2 - d0**2))**(2*n))
|
||||
return template
|
||||
|
||||
|
||||
def butterworthSelectFilter(image, d, n,W,kind):
|
||||
image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
|
||||
image = rgbToGray(image) # 图像灰度化
|
||||
f = np.fft.fft2(image) # 图像的傅里叶变换
|
||||
fshift = np.fft.fftshift(f) # 将低频移动到中心
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 1: # 巴特沃斯带阻滤波器
|
||||
d_matrix = ButterworthBand(image,W,d,n)
|
||||
elif kind == 4: # 巴特沃斯带通滤波器
|
||||
d_matrix = 1-ButterworthBand(image, W, d, n)
|
||||
# 与模板相乘后再傅里叶逆变换
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
@ -0,0 +1,66 @@
|
||||
|
||||
import cv2
|
||||
import numpy as np
|
||||
from function.GrayscaleTrans.BGR2GRAY import rgbToGray
|
||||
|
||||
# 高斯滤波器模板
|
||||
def make_transform_matrix(d,image,s1):
|
||||
transfor_matrix = np.zeros(image.shape)
|
||||
center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
|
||||
for i in range(transfor_matrix.shape[0]):
|
||||
for j in range(transfor_matrix.shape[1]):
|
||||
def cal_distance(pa, pb):
|
||||
from math import sqrt
|
||||
dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
|
||||
return dis
|
||||
|
||||
dis = cal_distance(center_point, (i, j))
|
||||
transfor_matrix[i, j] = np.exp(-(dis ** 2) / (2 * (d ** 2)))
|
||||
return transfor_matrix
|
||||
|
||||
def GaussianFilter(image,d,kind):
|
||||
image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
|
||||
image = rgbToGray(image)
|
||||
f = np.fft.fft2(image)
|
||||
fshift = np.fft.fftshift(f)
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 2:
|
||||
d_matrix = make_transform_matrix(d,image,s1)
|
||||
elif kind == 5:
|
||||
d_matrix = 1-make_transform_matrix(d,image,s1)
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
||||
|
||||
|
||||
# 定义函数,高斯带阻/通滤波模板
|
||||
def GaussianBand(src, w, d0):
|
||||
template = np.zeros(src.shape, dtype=np.float32) # 构建滤波器
|
||||
r, c = src.shape
|
||||
for i in np.arange(r):
|
||||
for j in np.arange(c):
|
||||
distance = np.sqrt((i - r / 2) ** 2 + (j - c / 2) ** 2)
|
||||
temp = ((distance**2 - d0**2)/(distance*w+0.00000001))**2
|
||||
template[i, j] = 1 - np.exp(-0.5 * temp)
|
||||
return template
|
||||
|
||||
def GaussianSelectFilter(image,d,W,kind):
|
||||
image = cv2.cvtColor(image, cv2.COLOR_RGBA2BGR)
|
||||
image = rgbToGray(image)
|
||||
f = np.fft.fft2(image)
|
||||
fshift = np.fft.fftshift(f)
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 2: # 高斯带阻滤波器
|
||||
d_matrix = GaussianBand(image,W,d)
|
||||
elif kind == 5: # 高斯带通滤波器
|
||||
d_matrix = 1-GaussianBand(image,W,d)
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift*d_matrix)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
||||
|
||||
|
||||
|
@ -0,0 +1,139 @@
|
||||
import numpy as np
|
||||
import cv2
|
||||
from function.GrayscaleTrans.BGR2GRAY import rgbToGray
|
||||
|
||||
def make_transform_matrix(d,image,s1):
|
||||
|
||||
transfor_matrix = np.zeros(image.shape)
|
||||
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
|
||||
for i in range(transfor_matrix.shape[0]):
|
||||
for j in range(transfor_matrix.shape[1]):
|
||||
def cal_distance(pa,pb):
|
||||
from math import sqrt
|
||||
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
|
||||
return dis
|
||||
dis = cal_distance(center_point,(i,j))
|
||||
if dis <= d:
|
||||
transfor_matrix[i,j]=1
|
||||
else:
|
||||
transfor_matrix[i,j]=0
|
||||
return transfor_matrix
|
||||
|
||||
def idealFilter(img,r,kind):
|
||||
'''
|
||||
理想滤波器
|
||||
:param img: 输入图像
|
||||
:param r: 滤波器半径
|
||||
:param kind: 滤波器类型
|
||||
:return: 滤波后的图像
|
||||
'''
|
||||
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR) # 四维转三维
|
||||
img = rgbToGray(img) # 灰度化
|
||||
f = np.fft.fft2(img) # 傅里叶变换
|
||||
fshift = np.fft.fftshift(f) # 将低频部分移到中心
|
||||
# 取绝对值:将复数变化成实数
|
||||
# 取对数的目的为了将数据变化到0-255
|
||||
s1 = np.log(np.abs(fshift))
|
||||
# d1 = make_transform_matrix(r, fshift, s1)
|
||||
if kind == 0: # 理想低通滤波
|
||||
d1 = make_transform_matrix(r, fshift, s1)
|
||||
elif kind == 3: # 理想高通滤波
|
||||
d1 = 1-make_transform_matrix(r, fshift, s1)
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
||||
|
||||
|
||||
def make_select_matrix(d,image,s1,W):
|
||||
"""
|
||||
构建理想选择滤波器
|
||||
:param d: 滤波器半径
|
||||
:param image: 图像的傅里叶变换
|
||||
:return:
|
||||
"""
|
||||
transfor_matrix = np.zeros(image.shape)
|
||||
center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
|
||||
for i in range(transfor_matrix.shape[0]):
|
||||
for j in range(transfor_matrix.shape[1]):
|
||||
def cal_distance(pa,pb):
|
||||
from math import sqrt
|
||||
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2) # 计算两点之间距离
|
||||
return dis
|
||||
dis = cal_distance(center_point,(i,j))
|
||||
# if dis <= d + W/2 and dis >= d - W/2:
|
||||
if dis <= d + W and dis >= d:
|
||||
transfor_matrix[i,j]=0
|
||||
else:
|
||||
transfor_matrix[i,j]=1
|
||||
return transfor_matrix
|
||||
|
||||
def idealSelectFilter(img,r,W,kind):
|
||||
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)
|
||||
img = rgbToGray(img)
|
||||
# 傅里叶变换
|
||||
f = np.fft.fft2(img)
|
||||
# 将低频部分移到中心
|
||||
fshift = np.fft.fftshift(f)
|
||||
# 取绝对值:将复数变化成实数
|
||||
# 取对数的目的为了将数据变化到0-255
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 0: # 理想带阻滤波器
|
||||
d1 = make_select_matrix(r, fshift, s1, W)
|
||||
elif kind == 3: # 理想带通滤波器
|
||||
d1 = 1-make_select_matrix(r, fshift, s1, W)
|
||||
# 与模板相乘后再傅里叶逆变换
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
||||
|
||||
def make_NotchFilter_matrix(d,image,s1):
|
||||
"""
|
||||
构建理想陷波滤波器
|
||||
:param d: 滤波器半径
|
||||
:param image: 图像的傅里叶变换
|
||||
:return:
|
||||
"""
|
||||
transfor_matrix = np.zeros(image.shape)
|
||||
# center_point = tuple(map(lambda x:(x-1)/2,s1.shape))
|
||||
center_point_1 = (s1.shape[0]/4,s1.shape[1]/2)
|
||||
center_point_2 = (3*s1.shape[0]/4,s1.shape[1]/2)
|
||||
for i in range(transfor_matrix.shape[0]):
|
||||
for j in range(transfor_matrix.shape[1]):
|
||||
def cal_distance(pa,pb):
|
||||
from math import sqrt
|
||||
dis = sqrt((pa[0]-pb[0])**2+(pa[1]-pb[1])**2)
|
||||
return dis
|
||||
dis_1 = cal_distance(center_point_1,(i,j))
|
||||
dis_2 = cal_distance(center_point_2,(i,j))
|
||||
# if dis <= d + W/2 and dis >= d - W/2:
|
||||
# if dis <= d + W and dis >= d:
|
||||
if dis_1 <= d or dis_2 <= d:
|
||||
transfor_matrix[i,j]=0
|
||||
else:
|
||||
transfor_matrix[i,j]=1
|
||||
return transfor_matrix
|
||||
|
||||
def idealNotchFilter(img,r,kind):
|
||||
img = cv2.cvtColor(img, cv2.COLOR_RGBA2BGR)
|
||||
img = rgbToGray(img)
|
||||
# 傅里叶变换
|
||||
f = np.fft.fft2(img)
|
||||
# 将低频部分移到中心
|
||||
fshift = np.fft.fftshift(f)
|
||||
# fshift = fshift.astype(np.uint8)
|
||||
# 取绝对值:将复数变化成实数
|
||||
# 取对数的目的为了将数据变化到0-255
|
||||
s1 = np.log(np.abs(fshift))
|
||||
if kind == 6:
|
||||
d1 = make_NotchFilter_matrix(r, fshift, s1)
|
||||
elif kind == 7:
|
||||
d1 = 1-make_NotchFilter_matrix(r, fshift, s1)
|
||||
img_d1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d1)))
|
||||
img_d1 = img_d1 / img_d1.max()
|
||||
img_d1 = img_d1 * 255
|
||||
img_d1 = img_d1.astype(np.uint8)
|
||||
return img_d1
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -0,0 +1,9 @@
|
||||
from cv2 import selectROI
|
||||
from function.GeometricTrans.LargeSmall import largeSmall
|
||||
|
||||
def cut(img,rate):
|
||||
|
||||
# 得到手动裁剪的矩形区域
|
||||
bbox = selectROI(img, False)
|
||||
cut = img[bbox[1]:bbox[1] + bbox[3], bbox[0]:bbox[0] + bbox[2]]
|
||||
return largeSmall(cut, rate)
|
@ -0,0 +1,13 @@
|
||||
# import cv2
|
||||
from cv2 import resize
|
||||
|
||||
def largeSmall(img,rate=100):
|
||||
|
||||
rate = rate / 100
|
||||
img_info = img.shape
|
||||
image_height = img_info[0]
|
||||
image_weight = img_info[1]
|
||||
desHeight = int(rate*image_height)
|
||||
desWeight = int(rate*image_weight)
|
||||
img = resize(img,(desWeight,desHeight))
|
||||
return img
|
@ -0,0 +1,15 @@
|
||||
import cv2
|
||||
import numpy as np
|
||||
|
||||
def mirror1(img,rate):
|
||||
print("111")
|
||||
cv2.flip(img, 1, img)
|
||||
return img
|
||||
|
||||
def mirror2(img,rate):
|
||||
cv2.flip(img, 0, img)
|
||||
return img
|
||||
|
||||
def mirror3(img,rate):
|
||||
cv2.flip(img, -1,img)
|
||||
return img
|
@ -0,0 +1,16 @@
|
||||
from cv2 import getRotationMatrix2D,warpAffine
|
||||
from math import fabs,sin,radians,cos
|
||||
|
||||
def ratate(img,degree=0):
|
||||
|
||||
height, width = img.shape[:2]
|
||||
# 旋转后的尺寸
|
||||
heightNew = int(width * fabs(sin(radians(degree))) + height * fabs(cos(radians(degree))))
|
||||
widthNew = int(height * fabs(sin(radians(degree))) + width * fabs(cos(radians(degree))))
|
||||
# 获得仿射变换矩阵
|
||||
matRotation = getRotationMatrix2D((width / 2, height / 2), degree, 1)
|
||||
matRotation[0, 2] += (widthNew - width) / 2
|
||||
matRotation[1, 2] += (heightNew - height) / 2
|
||||
# 进行仿射变换
|
||||
imgRotation = warpAffine(img, matRotation, (widthNew, heightNew), borderValue=(68, 68, 68))
|
||||
return imgRotation
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue