python----实战训练100例

1.qt统计人员薪资信息界面

薛蟠     4560 25
薛蝌     4460 25
薛宝钗   35776 23
薛宝琴   14346 18
王夫人   43360 45
王熙凤   24460 25
王子腾   55660 45
王仁     15034 65
尤二姐   5324 24
贾芹     5663 25
贾兰     13443 35
贾芸     4522 25
尤三姐   5905 22
贾珍     54603 35
from PySide2.QtWidgets import QApplication, QMainWindow, QPushButton,  QPlainTextEdit,QMessageBox

class Stats():
    def __init__(self):
        self.window = QMainWindow()
        self.window.resize(500, 400)
        self.window.move(300, 300)
        self.window.setWindowTitle('薪资统计')

        self.textEdit = QPlainTextEdit(self.window)
        self.textEdit.setPlaceholderText("请输入薪资表")
        self.textEdit.move(10, 25)
        self.textEdit.resize(300, 350)

        self.button = QPushButton('统计', self.window)
        self.button.move(380, 80)

        self.button.clicked.connect(self.handleCalc)


    def handleCalc(self):
        info = self.textEdit.toPlainText()

        # 薪资20000 以上 和 以下 的人员名单
        salary_above_20k = ''
        salary_below_20k = ''
        for line in info.splitlines():
            if not line.strip():
                continue
            parts = line.split(' ')
            # 去掉列表中的空字符串内容
            parts = [p for p in parts if p]
            name,salary,age = parts
            if int(salary) >= 20000:
                salary_above_20k += name + '\n'
            else:
                salary_below_20k += name + '\n'

        QMessageBox.about(self.window,
                    '统计结果',
                    f'''薪资20000 以上的有:\n{salary_above_20k}
                    \n薪资20000 以下的有:\n{salary_below_20k}'''
                    )

app = QApplication([])
stats = Stats()
stats.window.show()
app.exec_()

呈现效果:
在这里插入图片描述

2. BMI----身高体重指数(18.5-23.9-28)

def achieve_bmi(name):
    height = input("please input your height:")
    weight = input("please input your weight:")
    bmi = int(weight) / ((float(height) / 100) ** 2)
    if bmi < 18.5:
        print("{} are slim".format(name))
    elif 18.5 <= bmi < 24:
        print("{} are normal".format(name))
    elif 24 <= bmi < 28:
        print("{} are overweight".format(name))
    else:
        print("{} are too fat".format(name))


if __name__ == '__main__':
    name = input("please input your name:")
    achieve_bmi(name)

3. 简单购物车设计,程序执行时会列出所有商品,读者可以选择商品,如果所输入的商品在列表中则加入购物车,如果输入Q或q,则结束购物

message = "czy store"
products = ["dl", "cpp", "python", "opencv"]
storecar = []
print(message, '\n', products, '\n')
while True:
    msg = input("please input your product(q=quit):")
    if msg == 'q' or msg == 'Q':
        break
    else:
        if msg in products:
            storecar.append(msg)
print("your purchase list is:",storecar) 

4. 成绩排序
在这里插入图片描述

# /bin/bash

5. 读一篇文章,并按这篇文章中的文字出现频率排序

import calendar
for name in sorted(players.keys())   # 根据字典键排序
newList = sorted(noodles.items(), key = lambda item:item[1])
ret_vaule = dict.get(key[,default=None])
a = {1, 2, 3}
b = {2, 4, 6}
ab = a&b = a.intersection(b)
c = a|b = a.union(b)
d = a - b = a.difference(b)
None 独立成为一个数据类型,NoneType
lott = random.sample(range(1,50), 7) #
random.choice(a) 
time.sleep(1)   #让工作暂停
time.asctime()  #列出系统当前时间
time.localtime()  #列出当地时间:年月日时分秒星期几第几天夏令时间
for i in range(3):
    random.shuffle(a)
print(calendar.isleap(2020))   #是否闰年
print(calendar.month(2020,1))
print(calendar.calendar(2020))

在这里插入图片描述

在这里插入代码片

6. 抽奖代码
在这里插入图片描述

7. 实现一个简单的计算器

import sys
import re
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QMainWindow

class Calculator_Window(QMainWindow):
    def setupUi(self, CalculatorWindow):
        CalculatorWindow.setObjectName("Calculator")
        CalculatorWindow.resize(500, 800)

        # 1: 先打一条显示器
        self.showEdit = QtWidgets.QLineEdit(CalculatorWindow)
        self.showEdit.setGeometry(QtCore.QRect(20, 40, 300, 60))

        # 2: 打一个 九宫格 ,并把相应的数字打 [ 先打一个主框,左九宫格,右+-*/, 然后用窗口添加该主框 ]
        self.containerWidget = QtWidgets.QWidget(CalculatorWindow)
        self.containerWidget.setObjectName("containerWidget")

        # 3: 1 - 9 数字的布局
        self.gridLayoutWidget = QtWidgets.QWidget(self.containerWidget)
        self.gridLayoutWidget.setGeometry(QtCore.QRect(20, 100, 300, 500))
        self.gridLayoutWidget.setObjectName("gridLayoutWidget")
        self.gridLayout = QtWidgets.QGridLayout(self.gridLayoutWidget)
        self.gridLayout.setContentsMargins(0, 0, 0, 0) # 这里的 setContentsMargins 是左, 上, 右, 下
        self.gridLayout.setObjectName("gridLayout")
        self.btn_nmb_1 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_1.setObjectName("btn_nmb_1")
        self.gridLayout.addWidget(self.btn_nmb_1, 0, 0, 1, 1)
        self.btn_nmb_2 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_2.setObjectName("btn_nmb_2")
        self.gridLayout.addWidget(self.btn_nmb_2, 0, 1, 1, 1)
        self.btn_nmb_3 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_3.setObjectName("btn_nmb_3")
        self.gridLayout.addWidget(self.btn_nmb_3, 0, 2, 1, 1)
        self.btn_nmb_4 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_4.setObjectName("btn_nmb_4")
        self.gridLayout.addWidget(self.btn_nmb_4, 1, 0, 1, 1)
        self.btn_nmb_5 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_5.setObjectName("btn_nmb_5")
        self.gridLayout.addWidget(self.btn_nmb_5, 1, 1, 1, 1)
        self.btn_nmb_6 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_6.setObjectName("btn_nmb_6")
        self.gridLayout.addWidget(self.btn_nmb_6, 1, 2, 1, 1)
        self.btn_nmb_7 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_7.setObjectName("btn_nmb_7")
        self.gridLayout.addWidget(self.btn_nmb_7, 2, 0, 1, 1)
        self.btn_nmb_8 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_8.setObjectName("btn_nmb_8")
        self.gridLayout.addWidget(self.btn_nmb_8, 2, 1, 1, 1)
        self.btn_nmb_9 = QtWidgets.QPushButton(self.gridLayoutWidget)
        self.btn_nmb_9.setObjectName("btn_nmb_9")
        self.gridLayout.addWidget(self.btn_nmb_9, 2, 2, 1, 1)

        # + - * / 的垂直布局
        self.verticalLayoutWidget = QtWidgets.QWidget(self.containerWidget)
        self.verticalLayoutWidget.setGeometry(QtCore.QRect(340, 100, 70, 450))
        self.verticalLayoutWidget.setObjectName("verticalLayoutWidget")
        self.verticalLayout = QtWidgets.QVBoxLayout(self.verticalLayoutWidget)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")

        self.btn_add = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_add.setObjectName("btn_add")
        self.verticalLayout.addWidget(self.btn_add)
        self.btn_minus = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_minus.setObjectName("btn_minus")
        self.verticalLayout.addWidget(self.btn_minus)
        self.btn_multiply = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_multiply.setObjectName("btn_multiply")
        self.verticalLayout.addWidget(self.btn_multiply)
        self.btn_divide = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_divide.setObjectName("btn_divide")
        self.verticalLayout.addWidget(self.btn_divide)
        self.btn_equal = QtWidgets.QPushButton(self.verticalLayoutWidget)
        self.btn_equal.setObjectName("btn_equal")
        self.verticalLayout.addWidget(self.btn_equal)

        CalculatorWindow.setCentralWidget(self.containerWidget) # 窗口添加该主框

        self.retranslateUi(CalculatorWindow) # 设置文字的的函数
        QtCore.QMetaObject.connectSlotsByName(CalculatorWindow) # 连接到指定的槽

    def retranslateUi(self, CalculatorWindow): 
        _translate = QtCore.QCoreApplication.translate
        CalculatorWindow.setWindowTitle("计算器")

        self.showEdit.setText(_translate("CalculatorWindow", " 1 + 1 = 2"))  # 显示框

        # 1 - 9 按钮上的数字填充
        self.btn_nmb_1.setText(_translate("CalculatorWindow", "1"))
        self.btn_nmb_2.setText(_translate("CalculatorWindow", "2"))
        self.btn_nmb_3.setText(_translate("CalculatorWindow", "3"))
        self.btn_nmb_4.setText(_translate("CalculatorWindow", "4"))
        self.btn_nmb_5.setText(_translate("CalculatorWindow", "5"))
        self.btn_nmb_6.setText(_translate("CalculatorWindow", "6"))
        self.btn_nmb_7.setText(_translate("CalculatorWindow", "7"))
        self.btn_nmb_8.setText(_translate("CalculatorWindow", "8"))
        self.btn_nmb_9.setText(_translate("CalculatorWindow", "9"))

        # + - * / 的字符填充
        self.btn_add.setText(_translate("CalculatorWindow", "+"))
        self.btn_minus.setText(_translate("CalculatorWindow", "-"))
        self.btn_multiply.setText(_translate("CalculatorWindow", "*"))
        self.btn_divide.setText(_translate("CalculatorWindow", "/"))
        self.btn_equal.setText(_translate("CalculatorWindow", "="))

        # 给每个按钮的点击事件,统一处理
        self.btn_nmb_1.clicked.connect(self.btnClick)
        self.btn_nmb_2.clicked.connect(self.btnClick)
        self.btn_nmb_3.clicked.connect(self.btnClick)
        self.btn_nmb_4.clicked.connect(self.btnClick)
        self.btn_nmb_5.clicked.connect(self.btnClick)
        self.btn_nmb_6.clicked.connect(self.btnClick)
        self.btn_nmb_7.clicked.connect(self.btnClick)
        self.btn_nmb_8.clicked.connect(self.btnClick)
        self.btn_nmb_9.clicked.connect(self.btnClick)
        self.btn_add.clicked.connect(self.btnClick)
        self.btn_minus.clicked.connect(self.btnClick)
        self.btn_multiply.clicked.connect(self.btnClick)
        self.btn_divide.clicked.connect(self.btnClick)
        self.btn_equal.clicked.connect(self.btnClick)

    showString = ' '
    nmb1 = 0 # 第一个数字
    nmbOprerator = ''
    nmb2 = 0 # 第二个数字
    nmb3 = 0 # 第三个数字
    def btnClick(self): # 统一处理按钮事件; 思路:数字 + 符号 字符串  = 这种格式
        sender = self.sender()
        senderText = sender.text()
        self.valueNmb(str(senderText))

    def valueNmb(self, senderText): # 对按下的按钮进行计算
        if (senderText == "+" or senderText == "-" or senderText == "*" or senderText == "/"):
            self.showString += " " + senderText + " "
            self.nmb1 = re.sub(r'\D', "", self.showString) # 取符号前面的数字为 nmb1
            self.nmbOprerator = senderText
            self.showRes(str(self.nmb1) + " " + self.nmbOprerator + " ")
        elif (senderText == "="):
            self.showString += senderText
            nmb2Index = self.showString.find(self.nmbOprerator) + 1 # +1 是因为把 + - * / 的符号去掉
            self.nmb2 = self.showString[nmb2Index: -1]
            self.nmb3 = self.switchCal(int(self.nmb1), str(self.nmbOprerator), int(self.nmb2))
            self.showRes(str(self.nmb1) + " " + self.nmbOprerator + " " + str(self.nmb2) + " = " + str(self.nmb3))
        else:
            self.showString += senderText
            self.showRes(self.showString)
            

    def switchCal(self, nmb1, nmbOprerator, nmb2): # nmb3 进行计算
        nmb1 = int(nmb1)
        nmb2 = int(nmb2)
        if (nmbOprerator == "+"):
            return nmb1 + nmb2
        elif (nmbOprerator == "-"):
            return nmb1 - nmb2
        elif (nmbOprerator == "*"):
            return nmb1 * nmb2
        elif (nmbOprerator == "/"):
            return nmb1 / nmb2
        else:
            return 0

    def showRes(self, string): # 按钮改变显示的内容
        self.showEdit.setText(string)

if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    widget = QtWidgets.QMainWindow()
    window = Calculator_Window()
    window.setupUi(widget)
    widget.show()
    sys.exit(app.exec())

8. 创建一个密码生成器

import random  
import string  
  
def generate_password(length):  
    # 定义密码中包含的字符集  
    chars = string.ascii_letters + string.digits + string.punctuation  
    # 生成随机密码  
    password = ''.join(random.choice(chars) for i in range(length))  
    return password  
  
# 生成一个长度为10的随机密码  
password = generate_password(10)  
print(password)

9.创建一个简单的文本编辑器

import tkinter as tk  
from tkinter import filedialog, Text, Menu  
  
class TextEditor:  
    def __init__(self, master):  
        self.master = master  
        master.title("Simple Text Editor")  
        master.geometry("400x300")  
  
        self.text_frame = tk.Frame(master)  
        self.text_frame.pack(fill=tk.BOTH, expand=1)  
  
        self.text_area = Text(self.text_frame)  
        self.text_area.pack(fill=tk.BOTH, expand=1)  
  
        self.menu_bar = Menu(master)  
        master.config(menu=self.menu_bar)  
  
        self.file_menu = Menu(self.menu_bar, tearoff=0)  
        self.file_menu.add_command(label="New", command=self.new_file)  
        self.file_menu.add_command(label="Open", command=self.open_file)  
        self.file_menu.add_command(label="Save", command=self.save_file)  
        self.file_menu.add_command(label="Exit", command=master.quit)  
        self.menu_bar.add_cascade(label="File", menu=self.file_menu)  
  
    def new_file(self):  
        self.text_area.delete("1.0", tk.END)  
  
    def open_file(self):  
        file_path = filedialog.askopenfilename()  
        if file_path:  
            with open(file_path, "r") as file:  
                content = file.read()  
                self.text_area.insert(tk.END, content)  
  
    def save_file(self):  
        file_path = filedialog.asksaveasfilename()  
        if file_path:  
            with open(file_path, "w") as file:  
                content = self.text_area.get("1.0", tk.END)  
                file.write(content)  
  
root = tk.Tk()  
editor = TextEditor(root)  
root.mainloop()

10.实现一个命令行翻译工具

在这里插入代码片

11.实现一个天气查询工具

在这里插入代码片

12.实现一个电子邮件发送工具
13.实现一个日历应用
14.实现一个简单的任务管理器
15.实现一个音乐播放器
16.实现一个简单的图像处理工具
17.实现一个简单的网站爬虫
18.实现一个简单的网络速度测试工具

import time  
import socket  
  
# 目标服务器地址和端口号  
server_address = ('www.baidu.com', 80)  
  
# 测试下载速度  
def test_download_speed():  
    print('开始下载速度测试...')  
    start_time = time.time()  
    downloaded_bytes = 0  
    block_size = 1024 * 1024  # 1MB  
    data = b''  
    while True:  
        try:  
            # 连接服务器  
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:  
                s.connect(server_address)  
                # 下载数据块  
                while len(data) < block_size:  
                    received_bytes = s.recv(block_size - len(data))  
                    if not received_bytes:  
                        break  
                    data += received_bytes  
                downloaded_bytes += len(data)  
                elapsed_time = time.time() - start_time  
                download_speed = downloaded_bytes / elapsed_time / 1024 / 1024  # MB/s  
                print(f'下载速度:{download_speed:.5f} MB/s')  
        except KeyboardInterrupt:  
            break  
        except Exception as e:  
            print(f'下载速度测试出错:{e}')  
            break  
    print('下载速度测试完成。')  
  
# 测试上传速度  
def test_upload_speed():  
    print('开始上传速度测试...')  
    start_time = time.time()  
    uploaded_bytes = 0  
    block_size = 1024 * 1024  # 1MB  
    data = b'x' * block_size  # 填充数据块  
    while True:  
        try:  
            # 连接服务器  
            with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:  
                s.connect(server_address)  
                # 上传数据块  
                s.sendall(data)  
                uploaded_bytes += len(data)  
                elapsed_time = time.time() - start_time  
                upload_speed = uploaded_bytes / elapsed_time / 1024 / 1024  # MB/s  
                print(f'上传速度:{upload_speed:.2f} MB/s')  
        except KeyboardInterrupt:  
            break  
        except Exception as e:  
            print(f'上传速度测试出错:{e}')  
            break  
    print('上传速度测试完成。')  
  
if __name__ == '__main__':  
    test_download_speed()  # 先测试下载速度,再测试上传速度(可根据需要调整顺序)  
    test_upload_speed()  # 先测试下载速度,再测试上传速度(可根据需要调整顺序)

19.实现一个简单的数据可视化工具

20.实现一个简单的数据分析工具

21.实现一个简单的人脸检测工具

import cv2  
  
# 加载Haar Cascade分类器  
face_cascade = cv2.CascadeClassifier(cv2.data.haarcascades + 'haarcascade_frontalface_default.xml')  
  
# 读取图像  
img = cv2.imread('image.jpg')  
  
# 将图像转换为灰度图像  
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  
  
# 检测人脸  
faces = face_cascade.detectMultiScale(gray, 1.3, 5)  
  
# 在人脸周围绘制矩形框  
for (x, y, w, h) in faces:  
    cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2)  
  
# 显示结果图像  
cv2.imshow('img', img)  
cv2.waitKey(0)  
cv2.destroyAllWindows()

22.实现一个简单的数字识别工具
23.实现一个简单的自然语言处理工具
24.实现一个简单的机器学习模型
25.实现一个简单的深度学习模型
26.实现一个简单的推荐系统
27.实现一个简单的聊天机器人
28.实现一个简单的游戏
29. 实现一个简单的数据结构
30. 实现一个简单的算法
31. 实现一个简单的网络应用
32. 实现一个简单的图形用户界面
33. 实现一个简单的数据库应用
34. 实现一个简单的文件处理工具
35. 实现一个简单的进程管理工具
36. 实现一个简单的线程管理工具
37. 实现一个简单的并发编程工具
38. 实现一个简单的异步编程工具
39. 实现一个简单的数据存储工具
40. 实现一个简单的数据读取工具
41. 实现一个简单的数据清洗工具
42. 实现一个简单的数据转换工具
43. 实现一个简单的数据备份工具
44. 实现一个简单的数据恢复工具
45. 实现一个简单的数据安全工具
46. 实现一个简单的网络安全工具
47. 实现一个简单的密码管理工具
48. 实现一个简单的网络监控工具
49. 实现一个简单的数据加密工具
50. 实现一个简单的数据解密工具
51. 实现一个简单的压缩工具
52. 实现一个简单的解压工具
53. 实现一个简单的文件传输工具
54. 实现一个简单的协议分析工具
55. 实现一个简单的音频处理工具
56. 实现一个简单的视频处理工具
57.将图片转换为视频

import os
import cv2
from PIL import Image

def unlock_movie(path):
  cap = cv2.VideoCapture(path)
  suc = cap.isOpened()
  frame_count = 0
  while suc:
      frame_count += 1
      suc, frame = cap.read()
      params = []
      params.append(2)  # params.append(1)
      cv2.imwrite('frames\\%d.jpg' % frame_count, frame, params)

  cap.release()
  print('unlock movie: ', frame_count)


def  jpg_to_video(path, fps):
  fourcc = cv2.VideoWriter_fourcc(*"MJPG")
  images = os.listdir('frames')
  image = Image.open('frames/' + images[0])
  vw = cv2.VideoWriter(path, fourcc, fps, image.size)

os.chdir('frames')
for i in range(len(images)):
    # Image.open(str(image)+'.jpg').convert("RGB").save(str(image)+'.jpg')
    jpgfile = str(i + 1) + '.jpg'
    try:
        new_frame = cv2.imread(jpgfile)
        vw.write(new_frame)
    except Exception as exc:
        print(jpgfile, exc)
vw.release()
print(path, 'Synthetic success!')


if __name__ == '__main__':
  PATH_TO_MOVIES = os.path.join('test_movies', 'beautiful_mind2.mp4')
  PATH_TO_OUTCOME = os.path.join('detection_movies', 'beautiful_mind2_detection_1.avi')
  unlock_movie(PATH_TO_MOVIES)
  jpg_to_video(PATH_TO_OUTCOME, 24) 

58.图片画框

import os 
import cv2
f = open('eval.txt','r')
path = '/data/mmdetection/data/images'
pathresult = './result'
jpg_list = f.readlines()
path2 = []
for jpg in jpg_list:
    txt_list = jpg.strip().split(',')  
    if(txt_list[1] not in path2):
        image = cv2.imread(os.path.join(path,txt_list[1]))
        cv2.rectangle(image,(int(txt_list[4]),int(txt_list[5])),(int(txt_list[6]),int(txt_list[7])),(0,250,0),4)
        cv2.putText(image, txt_list[2], (int(txt_list[4]), int(txt_list[5])), cv2.FONT_HERSHEY_COMPLEX , 2, (0,0,250), 3)
        cv2.imwrite('./result/{}'.format(txt_list[1]), image)
        path2.append(txt_list[1])
    else:
        image = cv2.imread(os.path.join(pathresult,txt_list[1]))
        cv2.rectangle(image,(int(txt_list[4]),int(txt_list[5])),(int(txt_list[6]),int(txt_list[7])),(0,250,0),4)
        cv2.putText(image, txt_list[2], (int(txt_list[4]), int(txt_list[5])), cv2.FONT_HERSHEY_COMPLEX , 2, (0,0,250), 3)
        cv2.imwrite('./result/{}'.format(txt_list[1]), image)

59.利用opencv根据视频帧数获取指定时间段的视频

import cv2
print(cv2.__version__)
videoCapture = cv2.VideoCapture('3.mp4')
fps = 10 
size = (1920,1080)
videoWriter0 =cv2.VideoWriter('det.avi',cv2.VideoWriter_fourcc('X','V','I','D'),fps,size)
i = 0
 
while True:
    success,frame = videoCapture.read()
    if success:
        i += 1
        print('i = ',i)
        if(25*4095 <= i <= 25*4162):
            videoWriter0.write(frame)
    else:
        print('end')   
        break  

60.实现VOC数据集转化为COCO数据集

# -*- coding:utf-8 -*-
# !/usr/bin/env python
 
import argparse
import json
import matplotlib.pyplot as plt
import skimage.io as io
import cv2
from labelme import utils
import numpy as np
import glob
import PIL.Image
import os,sys
 
 
class PascalVOC2coco(object):
    def __init__(self, xml=[], save_json_path='./new.json'):
        '''
        :param xml: 所有Pascal VOC的xml文件路径组成的列表
        :param save_json_path: json保存位置
        '''
        self.xml = xml
        self.save_json_path = save_json_path
        self.images = []
        self.categories = []
        self.annotations = []
        # self.data_coco = {}
        self.label = []
        self.annID = 1
        self.height = 0
        self.width = 0
        self.ob = []
 
        self.save_json()
 
    def data_transfer(self):
        for num, json_file in enumerate(self.xml):
 
            # 进度输出
            sys.stdout.write('\r>> Converting image %d/%d' % (
                num + 1, len(self.xml)))
            sys.stdout.flush()
 
            self.json_file = json_file
            #print("self.json", self.json_file)
            self.num = num 
            #print(self.num)
            path = os.path.dirname(self.json_file)
            #print(path)
            path = os.path.dirname(path)
            print(path)
            # path=os.path.split(self.json_file)[0]
            # path=os.path.split(path)[0]
            obj_path = glob.glob(os.path.join(path, 'SegmentationObject', '*.png'))
            #print(obj_path)
            with open(json_file, 'r') as fp:
                #print(fp)
                flag = 0
                for p in fp:
                    #print(p)
                    # if 'folder' in p:
                    #     folder =p.split('>')[1].split('<')[0]
                    f_name = 1
                    if 'filename' in p:
                        self.filen_ame = p.split('>')[1].split('<')[0]
                        print(self.filen_ame)
                        f_name = 0
 
                        self.path = os.path.join(path, 'SegmentationObject', self.filen_ame.split('.')[0] + '.png')
                        #if self.path not in obj_path:
                        #    break
 
 
                    if 'width' in p:
                        self.width = int(p.split('>')[1].split('<')[0])
                        #print(self.width)
                    if 'height' in p:
                        self.height = int(p.split('>')[1].split('<')[0])
 
                        self.images.append(self.image())
                        #print(self.image())
 
                    if flag == 1:
                        self.supercategory = self.ob[0]
                        if self.supercategory not in self.label:
                            self.categories.append(self.categorie())
                            self.label.append(self.supercategory)
 
                        # 边界框
                        x1 = int(float(self.ob[-4]));
                        y1 = int(float(self.ob[-3]));
                        x2 = int(float(self.ob[-2]));
                        y2 = int(float(self.ob[-1]));
                        self.rectangle = [x1, y1, x2, y2]
                        self.bbox = [x1, y1, x2 - x1, y2 - y1]  # COCO 对应格式[x,y,w,h]
 
                        self.annotations.append(self.annotation())
                        self.annID += 1
                        self.ob = []
                        flag = 0
                    elif f_name == 1:
                        if 'name' in p:
                            self.ob.append(p.split('>')[1].split('<')[0])
 
                        if 'xmin' in p:
                            self.ob.append(p.split('>')[1].split('<')[0])
 
                        if 'ymin' in p:
                            self.ob.append(p.split('>')[1].split('<')[0])
 
                        if 'xmax' in p:
                            self.ob.append(p.split('>')[1].split('<')[0])
 
                        if 'ymax' in p:
                            self.ob.append(p.split('>')[1].split('<')[0])
                            flag = 1
 
                    '''
                    if '<object>' in p:
                        # 类别
                        print(next(fp))
                        d = [next(fp).split('>')[1].split('<')[0] for _ in range(7)]
                        self.supercategory = d[0]
                        if self.supercategory not in self.label:
                            self.categories.append(self.categorie())
                            self.label.append(self.supercategory)
                        # 边界框
                        x1 = int(d[-4]);
                        y1 = int(d[-3]);
                        x2 = int(d[-2]);
                        y2 = int(d[-1])
                        self.rectangle = [x1, y1, x2, y2]
                        self.bbox = [x1, y1, x2 - x1, y2 - y1]  # COCO 对应格式[x,y,w,h]
                        self.annotations.append(self.annotation())
                        self.annID += 1
                     '''
 
        sys.stdout.write('\n')
        sys.stdout.flush()
 
    def image(self):
        image = {}
        image['height'] = self.height
        image['width'] = self.width
        image['id'] = self.num + 1

        name1111,name2222 = os.path.split(self.json_file)
        name3333,name4444 = os.path.splitext(name2222)
        name5555 = name3333 + ".jpg"

        image['file_name'] = name5555

        return image
 
    def categorie(self):
        categorie = {}
        categorie['supercategory'] = self.supercategory
        categorie['id'] = len(self.label) + 1  # 0 默认为背景
        categorie['name'] = self.supercategory
        return categorie
 
    def annotation(self):
        annotation = {}
        # annotation['segmentation'] = [self.getsegmentation()]
        annotation['segmentation'] = [list(map(float, self.getsegmentation()))]
        annotation['iscrowd'] = 0
        annotation['image_id'] = self.num + 1
        # annotation['bbox'] = list(map(float, self.bbox))
        annotation['bbox'] = self.bbox
        annotation['category_id'] = self.getcatid(self.supercategory)
        annotation['id'] = self.annID
        return annotation
 
    def getcatid(self, label):
        for categorie in self.categories:
            if label == categorie['name']:
                return categorie['id']
        return -1
 
    def getsegmentation(self):
 
        try:
            mask_1 = cv2.imread(self.path, 0)
            mask = np.zeros_like(mask_1, np.uint8)
            rectangle = self.rectangle
            mask[rectangle[1]:rectangle[3], rectangle[0]:rectangle[2]] = mask_1[rectangle[1]:rectangle[3],
                                                                         rectangle[0]:rectangle[2]]
 
            # 计算矩形中点像素值
            mean_x = (rectangle[0] + rectangle[2]) // 2
            mean_y = (rectangle[1] + rectangle[3]) // 2
 
            end = min((mask.shape[1], int(rectangle[2]) + 1))
            start = max((0, int(rectangle[0]) - 1))
 
            flag = True
            for i in range(mean_x, end):
                x_ = i;
                y_ = mean_y
                pixels = mask_1[y_, x_]
                if pixels != 0 and pixels != 220:  # 0 对应背景 220对应边界线
                    mask = (mask == pixels).astype(np.uint8)
                    flag = False
                    break
            if flag:
                for i in range(mean_x, start, -1):
                    x_ = i;
                    y_ = mean_y
                    pixels = mask_1[y_, x_]
                    if pixels != 0 and pixels != 220:
                        mask = (mask == pixels).astype(np.uint8)
                        break
            self.mask = mask
 
            return self.mask2polygons()
 
        except:
            return [0]
 
    def mask2polygons(self):
        contours = cv2.findContours(self.mask, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)  # 找到轮廓线
        bbox=[]
        for cont in contours[1]:
            [bbox.append(i) for i in list(cont.flatten())]
            # map(bbox.append,list(cont.flatten()))
        return bbox # list(contours[1][0].flatten())
 
    # '''
    def getbbox(self, points):
        # img = np.zeros([self.height,self.width],np.uint8)
        # cv2.polylines(img, [np.asarray(points)], True, 1, lineType=cv2.LINE_AA)  # 画边界线
        # cv2.fillPoly(img, [np.asarray(points)], 1)  # 画多边形 内部像素值为1
        polygons = points
        mask = self.polygons_to_mask([self.height, self.width], polygons)
        return self.mask2box(mask)
 
    def mask2box(self, mask):
        '''从mask反算出其边框
        mask:[h,w]  0、1组成的图片
        1对应对象,只需计算1对应的行列号(左上角行列号,右下角行列号,就可以算出其边框)
        '''
        # np.where(mask==1)
        index = np.argwhere(mask == 1)
        rows = index[:, 0]
        clos = index[:, 1]
        # 解析左上角行列号
        left_top_r = np.min(rows)  # y
        left_top_c = np.min(clos)  # x
 
        # 解析右下角行列号
        right_bottom_r = np.max(rows)
        right_bottom_c = np.max(clos)
 
        # return [(left_top_r,left_top_c),(right_bottom_r,right_bottom_c)]
        # return [(left_top_c, left_top_r), (right_bottom_c, right_bottom_r)]
        # return [left_top_c, left_top_r, right_bottom_c, right_bottom_r]  # [x1,y1,x2,y2]
        return [left_top_c, left_top_r, right_bottom_c - left_top_c,
                right_bottom_r - left_top_r]  # [x1,y1,w,h] 对应COCO的bbox格式
 
    def polygons_to_mask(self, img_shape, polygons):
        mask = np.zeros(img_shape, dtype=np.uint8)
        mask = PIL.Image.fromarray(mask)
        xy = list(map(tuple, polygons))
        PIL.ImageDraw.Draw(mask).polygon(xy=xy, outline=1, fill=1)
        mask = np.array(mask, dtype=bool)
        return mask
 
    # '''
    def data2coco(self):
        data_coco = {}
        data_coco['images'] = self.images
        data_coco['categories'] = self.categories
        data_coco['annotations'] = self.annotations
        return data_coco
 
    def save_json(self):
        self.data_transfer()
        self.data_coco = self.data2coco()
        # 保存json文件
        json.dump(self.data_coco, open(self.save_json_path, 'w'), indent=4)  # indent=4 更加美观显示
 
 
xml_file = glob.glob('./Annotations/*.xml')
PascalVOC2coco(xml_file, 'train.json')

61.爬取猫眼电影

from urllib import request
import time
import re
import pymongo
 
class MaoyanSpider(object):
    def __init__(self):
        self.baseurl = 'https://maoyan.com/board/4?offset='
        self.headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        }
        # 爬取页数计数
        self.page = 1
        self.conn = pymongo.MongoClient('localhost', 27017)
        self.db = self.conn['maoyandb']
        self.myset = self.db['filmset']
 
    # 获取页面
    def get_page(self,url):
        req = request.Request(url,headers=self.headers)
        res = request.urlopen(req)
        html = res.read().decode('utf-8')
        # 直接调用解析函数
        self.parse_page(html)
 
    # 解析页面
    def parse_page(self,html):
        # 正则解析
        p = re.compile('<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>',re.S)
        r_list = p.findall(html)
        # r_list : [('霸王别姬','张国荣','1993'),(),()]
        self.write_mongo(r_list)
 
    # 保存数据(从终端输出)
    def write_mongo(self, r_list):
        for rt in r_list:
            film = {
                '名称': rt[0].strip(),
                '主演': rt[1].strip(),
                '时间': rt[2].strip()
            }
            self.myset.insert_one(film)
 
 
    # 主函数
    def main(self):
        # 用range函数可获取某些查询参数的值
        for offset in range(0, 41, 10):
            url = self.baseurl + str(offset)
            self.get_page(url)
            print('第%d页爬取成功' % self.page)
            self.page += 1
            time.sleep(1)
 
 
if __name__ == '__main__':
    spider = MaoyanSpider()
    spider.main()
from urllib import request
import re
import time
import random
import pymysql
 
 
class MaoyanSpider(object):
    def __init__(self):
        self.base_url = 'https://maoyan.com/board/4?offset={}'
        self.headers = {
            'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        }
        self.page = 1
        self.db = pymysql.connect(
            'localhost', 'root', '123456', 'maoyandb', charset='utf8'
        )
        self.cursor = self.db.cursor()
 
    def get_pages(self, url):
        req = request.Request(url, headers=self.headers)
        res = request.urlopen(req)
        html = res.read().decode('utf-8')
        self.parse_page(html)
 
    def parse_page(self, html):
        pattern = re.compile('<a href.*?title="(.*?)".*?<p class="star">(.*?)</p>.*?<p class="releasetime">(.*?)</p>', re.S)
        results = pattern.findall(html)
        self.write_sql(results)
 
    def write_sql(self, results):
        data_list = []
        for film in results:
            L = [
                film[0].strip(),
                film[1].strip(),
                film[2].strip()[5:15]]
            data_list.append(L)
        ins = 'insert into filmset values(%s,%s,%s)'
        self.cursor.executemany(ins, data_list)
        self.db.commit()
 
    def main(self):
        # 用range函数可获取某些查询参数的值
        for offset in range(0, 41, 10):
            url = self.base_url.format(str(offset))
            self.get_pages(url)
            print('第%d页爬取成功' % self.page)
            self.page += 1
            time.sleep(random.randint(1, 2))
        self.cursor.close()
        self.db.close()
 
 
if __name__ == '__main__':
    spider = MaoyanSpider()
    spider.main()
from urllib import request
import time
import re
import csv
 
class MaoyanSpider(object):
    def __init__(self):
        self.baseurl = 'https://maoyan.com/board/4?offset='
        self.headers = {
            'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36'
        }
        # 爬取页数计数
        self.page = 1
 
    # 获取页面
    def get_page(self,url):
        req = request.Request(url,headers=self.headers)
        res = request.urlopen(req)
        html = res.read().decode('utf-8')
        # 直接调用解析函数
        self.parse_page(html)
 
    # 解析页面
    def parse_page(self,html):
        # 正则解析
        p = re.compile('<div class="movie-item-info">.*?title="(.*?)".*?class="star">(.*?)</p>.*?releasetime">(.*?)</p>',re.S)
        r_list = p.findall(html)
        self.write_page(r_list)
 
    # 保存数据
   def write_page(self,r_list):
    film_list = []
    with open('maoyanfilm.csv','a') as f:
        writer = csv.writer(f)
        for rt in r_list:
            film = ( rt[0].strip(),rt[1].strip(),rt[2].strip() )
            film_list.append(film)
        writer.writerows(film_list)
 
 
    # 主函数
    def main(self):
        # 用range函数可获取某些查询参数的值
        for offset in range(0,41,10):
            url = self.baseurl + str(offset)
            self.get_page(url)
            print('第%d页爬取成功' % self.page)
            self.page += 1
            time.sleep(1)
 
if __name__ == '__main__':
    spider = MaoyanSpider()
    spider.main()

62.图像量化

import numpy as np
import scipy.misc as sm
import scipy.ndimage as sn
import sklearn.cluster as sc
import matplotlib.pyplot as mp
 
 
# 通过K均值聚类量化图像中的颜色
def quant(image, n_clusters):
    x = image.reshape(-1, 1)
    model = sc.KMeans(n_clusters=n_clusters)
    model.fit(x)
    y = model.labels_
    centers = model.cluster_centers_.ravel()
    return centers[y].reshape(image.shape)
 
 
original = sm.imread('../data/lily.jpg', True)
quant4 = quant(original, 4)
quant3 = quant(original, 3)
quant2 = quant(original, 2)
mp.figure('Image Quant', facecolor='lightgray')
mp.subplot(221)
mp.title('Original', fontsize=16)
mp.axis('off')
mp.imshow(original, cmap='gray')
mp.subplot(222)
mp.title('Quant-4', fontsize=16)
mp.axis('off')
mp.imshow(quant4, cmap='gray')
mp.subplot(223)
mp.title('Quant-3', fontsize=16)
mp.axis('off')
mp.imshow(quant3, cmap='gray')
mp.subplot(224)
mp.title('Quant-2', fontsize=16)
mp.axis('off')
mp.imshow(quant2, cmap='gray')
mp.tight_layout()
mp.show()

63.kmeans

import numpy as np
import sklearn.cluster as sc
import matplotlib.pyplot as mp
x=np.loadtxt('multiple3.txt',delimiter=',')
model = sc.KMeans(n_clusters=6)
model.fit(x)
centers=model.cluster_centers_
n=500
l,r=x[:,0].min()-1,x[:,0].max()+1
b,t=x[:,1].min()-1,x[:,1].max()+1
grid_x=np.meshgrid(np.linspace(l,r,n),np.linspace(b,t,n))
flat_x=np.column_stack((grid_x[0].ravel(),grid_x[1].ravel()))
flat_y=model.predict(flat_x)
grid_y=flat_y.reshape(grid_x[0].shape)
pred_y=model.predict(x)
mp.figure('kmeans',facecolor='lightgray')
mp.title('Kmeans',fontsize=20)
mp.xlabel('x',fontsize=20)
mp.ylabel('y',fontsize=20)
mp.tick_params(labelsize=10)
mp.pcolormesh(grid_x[0],grid_x[1],grid_y,cmap='gray')
mp.scatter(x[:,0],x[:,1],c=pred_y,cmap='brg',s=80)
mp.scatter(centers[:,0],centers[:,1],marker='+',c='gold',s=1000,linewidth=1)
mp.show()

# 手撕
import numpy as np
import matplotlib.pyplot as plt
 
# 加载数据
def loadDataSet(fileName):
    data = np.loadtxt(fileName,delimiter=',')
    return data
 
# 欧氏距离计算
def distEclud(x,y):
    return np.sqrt(np.sum((x-y)**2))  # 计算欧氏距离
 
# 为给定数据集构建一个包含K个随机质心的集合
def randCent(dataSet,k):
    m,n = dataSet.shape
    centroids = np.zeros((k,n))
    for i in range(k):
        index = int(np.random.uniform(0,m)) #
        centroids[i,:] = dataSet[index,:]
    return centroids
 
# k均值聚类
def KMeans(dataSet,k):
 
    m = np.shape(dataSet)[0]  #行的数目
    # 第一列存样本属于哪一簇
    # 第二列存样本的到簇的中心点的误差
    clusterAssment = np.mat(np.zeros((m,2)))
    clusterChange = True
 
    # 第1步 初始化centroids
    centroids = randCent(dataSet,k)
    while clusterChange:
        clusterChange = False
 
        # 遍历所有的样本(行数)
        for i in range(m):
            minDist = 100000.0
            minIndex = -1
 
            # 遍历所有的质心
            #第2步 找出最近的质心
            for j in range(k):
                # 计算该样本到质心的欧式距离
                distance = distEclud(centroids[j,:],dataSet[i,:])
                if distance < minDist:
                    minDist = distance
                    minIndex = j
            # 第 3 步:更新每一行样本所属的簇
            if clusterAssment[i,0] != minIndex:
                clusterChange = True
                clusterAssment[i,:] = minIndex,minDist**2
        #第 4 步:更新质心
        for j in range(k):
            pointsInCluster = dataSet[np.nonzero(clusterAssment[:,0].A == j)[0]]  # 获取簇类所有的点
            centroids[j,:] = np.mean(pointsInCluster,axis=0)   # 对矩阵的行求均值
 
    print("Congratulations,cluster complete!")
    return centroids,clusterAssment
 
def showCluster(dataSet,k,centroids,clusterAssment):
    m,n = dataSet.shape
    if n != 2:
        print("数据不是二维的")
        return 1
 
    mark = ['or', 'ob', 'og', 'ok', '^r', '+r', 'sr', 'dr', '<r', 'pr']
    if k > len(mark):
        print("k值太大了")
        return 1
 
    # 绘制所有的样本
    for i in range(m):
        markIndex = int(clusterAssment[i,0])
        plt.plot(dataSet[i,0],dataSet[i,1],mark[markIndex])
 
    mark = ['Dr', 'Db', 'Dg', 'Dk', '^b', '+b', 'sb', 'db', '<b', 'pb']
    # 绘制质心
    for i in range(k):
        plt.plot(centroids[i,0],centroids[i,1],mark[i])
 
    plt.show()
dataSet = loadDataSet("multiple3.txt")
k = 4
centroids,clusterAssment = KMeans(dataSet,k)
 
showCluster(dataSet,k,centroids,clusterAssment)
  1. mixup
import matplotlib.pyplot as plt
import matplotlib.image as Image
import cv2
im1 = Image.imread("cat1.jpg") 
im1 = im1/255.
im2 = Image.imread("cat2.jpg")
im2 = im2/255.
 
lam= 4*0.1  
im_mixup = (im1*lam+im2*(1-lam))
cv2.imwrite('mixup.jpg', im_mixup) 
plt.imshow(im_mixup)
plt.show()


##way 2
#!/usr/bin/env python
#coding:utf-8
import cv2
import sys
import os
import random
import numpy as np
from PIL import Image
from io import BytesIO
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element
 
 
def aHash(img):
    # 均值哈希算法
    # 缩放为8*8
    img = cv2.resize(img, (8, 8))
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # s为像素和初值为0,hash_str为hash值初值为''
    s = 0
    hash_str = ''
    # 遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s = s+gray[i, j]
    # 求平均灰度
    avg = s/64
    # 灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if gray[i, j] > avg:
                hash_str = hash_str+'1'
            else:
                hash_str = hash_str+'0'
    return hash_str
 
 
def dHash(img):
    # 差值哈希算法
    # 缩放8*8
    img = cv2.resize(img, (9, 8))
    # 转换灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    hash_str = ''
    # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        for j in range(8):
            if gray[i, j] > gray[i, j+1]:
                hash_str = hash_str+'1'
            else:
                hash_str = hash_str+'0'
    return hash_str
 
 
def pHash(img):
    # 感知哈希算法
    # 缩放32*32
    img = cv2.resize(img, (32, 32))   # , interpolation=cv2.INTER_CUBIC
 
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型,再进行dct变换
    dct = cv2.dct(np.float32(gray))
    # opencv实现的掩码操作
    dct_roi = dct[0:8, 0:8]
 
    hash = []
    avreage = np.mean(dct_roi)
    for i in range(dct_roi.shape[0]):
        for j in range(dct_roi.shape[1]):
            if dct_roi[i, j] > avreage:
                hash.append(1)
            else:
                hash.append(0)
    return hash
 
 
def calculate(image1, image2):
    # 灰度直方图算法
    # 计算单通道的直方图的相似值
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 计算直方图的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + \
                (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree
 
 
def classify_hist_with_split(image1, image2, size=(256, 256)):
    # RGB每个通道的直方图相似度
    # 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    sub_image1 = cv2.split(image1)
    sub_image2 = cv2.split(image2)
    sub_data = 0
    for im1, im2 in zip(sub_image1, sub_image2):
        sub_data += calculate(im1, im2)
    sub_data = sub_data / 3
    return sub_data
 
 
def cmpHash(hash1, hash2):
    # Hash值对比
    # 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定,但是比较的时候必须是相同的顺序。
    # 对比两幅图的指纹,计算汉明距离,即两个64位的hash值有多少是不一样的,不同的位数越小,图片越相似
    # 汉明距离:一组二进制数据变成另一组数据所需要的步骤,可以衡量两图的差异,汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样
    n = 0
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 不相等则n计数+1,n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return n
 
 
def getImageByUrl(url):
    # 根据图片url 获取图片对象
    html = requests.get(url, verify=False)
    image = Image.open(BytesIO(html.content))
    return image
 
 
def PILImageToCV():
    # PIL Image转换成OpenCV格式
    path = "/Users/waldenz/Documents/Work/doc/TestImages/t3.png"
    img = Image.open(path)
    plt.subplot(121)
    plt.imshow(img)
    print(isinstance(img, np.ndarray))
    img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    print(isinstance(img, np.ndarray))
    plt.subplot(122)
    plt.imshow(img)
    plt.show()
 
 
def CVImageToPIL():
    # OpenCV图片转换为PIL image
    path = "/Users/waldenz/Documents/Work/doc/TestImages/t3.png"
    img = cv2.imread(path)
    # cv2.imshow("OpenCV",img)
    plt.subplot(121)
    plt.imshow(img)
 
    img_b = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(122)
    plt.imshow(img_b)
    plt.show()
 
def bytes_to_cvimage(filebytes):
    # 图片字节流转换为cv image
    image = Image.open(filebytes)
    img = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
    return img
 
def runAllImageSimilaryFun(img_a, img_b):
    # 均值、差值、感知哈希算法三种算法值越小,则越相似,相同图片值为0
    # 三直方图算法和单通道的直方图 0-1之间,值越大,越相似。 相同图片为1
 
    # t1,t2   14;19;10;  0.70;0.75
    # t1,t3   39 33 18   0.58 0.49
    # s1,s2  7 23 11     0.83 0.86  挺相似的图片
    # c1,c2  11 29 17    0.30 0.31
 
    # if para1.startswith("http"):
    #      # 根据链接下载图片,并转换为opencv格式
    #     img_a = getImageByUrl(para1)
    #     img_a = cv2.cvtColor(np.asarray(img_a), cv2.COLOR_RGB2BGR)
 
    #     img_b = getImageByUrl(para2)
    #     img_b = cv2.cvtColor(np.asarray(img_b), cv2.COLOR_RGB2BGR)
    # else:
    #     # 通过imread方法直接读取物理路径
    #     img_a = cv2.imread(para1)
    #     img_b = cv2.imread(para2)
 
    hash1 = aHash(img_a)
    hash2 = aHash(img_b)
    n1 = cmpHash(hash1, hash2)
    n1 = 1-float(n1/64)
    # print('均值哈希算法相似度aHash:', n1)
 
    hash1 = dHash(img_a)
    hash2 = dHash(img_b)
    n2 = cmpHash(hash1, hash2)
    n2 = 1 - float(n2/64)
    # print('差值哈希算法相似度dHash:', n2)
 
    hash1 = pHash(img_a)
    hash2 = pHash(img_b)
    n3 = cmpHash(hash1, hash2)
    n3 = 1-float(n3/64)
    # print('感知哈希算法相似度pHash:', n3)
 
    # n4 = classify_hist_with_split(img_a, img_b)
    # n4 = round(n4[0], 2)
    # print('三直方图算法相似度:', n4)
 
    # n5 = calculate(img_a, img_b)
    # n5 = n5[0]
    # print("单通道的直方图", n5)
    # print("%d %d %d %.2f %.2f " % (n1, n2, n3, round(n4[0], 2), n5[0]))
    # print("%.2f %.2f %.2f %.2f %.2f " % (1-float(n1/64), 1 -
    #                                      float(n2/64), 1-float(n3/64), round(n4[0], 2), n5[0]))
    
    print(n1,n2,n3)
    print(min(n1,n2,n3))
    return min(n1,n2,n3)
 
    # plt.subplot(121)
    # plt.imshow(Image.fromarray(cv2.cvtColor(img_a, cv2.COLOR_BGR2RGB)))
    # plt.subplot(122)
    # plt.imshow(Image.fromarray(cv2.cvtColor(img_b, cv2.COLOR_BGR2RGB)))
    # plt.show()


def prettyXml(element, indent, newline, level=0):  
    if element:  
        if element.text == None or element.text.isspace():  
            element.text = newline + indent * (level + 1)
        else:
            element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
    temp = list(element)  
    for subelement in temp:
        if temp.index(subelement) < (len(temp) - 1): 
            subelement.tail = newline + indent * (level + 1)
        else: 
            subelement.tail = newline + indent * level
        prettyXml(subelement, indent, newline, level=level + 1)  


def write_xml(box,name,pose, truncated, difficult, root,tree,outpath):
    element = Element('object')
    one1 = Element('bndbox')
    two1 = Element('xmin')
    two2 = Element('ymin')
    two3 = Element('xmax')
    two4 = Element('ymax')
    two1.text = box[0]
    two2.text = box[1]
    two3.text = box[2]
    two4.text = box[3]
    name_node = Element('name')
    name_node.text = name
    name_node1 = Element('pose')
    name_node1.text = pose
    name_node2 = Element('truncated')
    name_node2.text = truncated
    name_node3 = Element('difficult')
    name_node3.text = difficult
    element.append(name_node)
    element.append(name_node1)
    element.append(name_node2)
    element.append(name_node3)
    one1.append(two1)
    one1.append(two2)
    one1.append(two3)
    one1.append(two4)
    element.append(one1)
    root.append(element)
    prettyXml(root, '\t', '\n')
    print('save successful %s'%outpath)
    tree.write(outpath, encoding='utf-8', xml_declaration=True)


def write_xml_simple(box,name,root,tree,outpath):
    element = Element('object')
    one1 = Element('bndbox')
    name_node = Element('name')
    two1 = Element('xmin')
    two2 = Element('ymin')
    two3 = Element('xmax')
    two4 = Element('ymax')
    two1.text = box[0]
    two2.text = box[1]
    two3.text = box[2]
    two4.text = box[3]
    name_node.text = name
    print('------name--------',name)

    element.append(name_node)
    one1.append(two1)
    one1.append(two2)
    one1.append(two3)
    one1.append(two4)
    element.append(one1)
    root.append(element)
    print('-------bndbox-------',element)
    prettyXml(root, '\t', '\n')
    print('save successful %s'%outpath)
    tree.write(outpath, encoding='utf-8', xml_declaration=True)

def mixup_with_xml(input_patha,input_pathb,xml_patha, xml_pathb,new_output_jpg, new_output_xml):
    for a in os.listdir(input_patha):
        name_a = os.path.split(a)[1][3:-4]
        img_a = cv2.imread(os.path.join(input_patha,a))
        root = ET.parse(os.path.join(xml_patha,a[:-4]+'.xml')).getroot()
        num = 0
        #for b in random.sample(os.listdir(input_pathb),400):
        for b in os.listdir(input_pathb):
            name_b = os.path.split(b)[1][3:-4]
            # name_b = name_a + 1
            img_b = cv2.imread(os.path.join(input_pathb,b))
            # sim_jpg = []
            # sim_jpg.append(runAllImageSimilaryFun(img_a,img_b))
            
            if int(name_a)==int(name_b) + 1: #and runAllImageSimilaryFun(img_a,img_b) > 0.4:
                num = num + 1
                #print(runAllImageSimilaryFun(img_a,img_b))
                canshu_a = 0.6
                canshu_b = 0.6
                # canshu_a = round(random.uniform(0.3,0.7),1)
                # canshu_b = round(random.uniform(0.3,0.7),1)
                # print('------a------',canshu_a,'\n------b------',canshu_b)
                # if num < 5:
                img_new = cv2.addWeighted(img_a, canshu_a, img_b, canshu_b, 0)
                canshu_a = str(canshu_a)[-1]
                canshu_b = str(canshu_b)[-1]
                cv2.imwrite(os.path.join(new_output_jpg, name_a+'_'+str(canshu_a) +'_mixup3_' + str(canshu_b) + '_'+ name_b +'.jpg'),img_new)
                xml_path_b  = os.path.join(xml_pathb,b[:-4]+'.xml')
                if os.path.exists(xml_path_b):
                    treeb = ET.parse(xml_path_b)
                    rootb = treeb.getroot()
                    for object in root.findall('object'):
                        box =[object.find('bndbox').find('xmin').text,
                        object.find('bndbox').find('ymin').text,
                        object.find('bndbox').find('xmax').text,
                        object.find('bndbox').find('ymax').text]
                        name = object.find('name').text
                        print('----box----name----',box,name)

                        write_xml_simple(box, name, rootb, treeb, os.path.join(new_output_xml, name_a+'_'+str(canshu_a) +'_mixup3_' + str(canshu_b) + '_'+ name_b +'.xml'))


if __name__ == "__main__":
    input_pathb = "./JPEGImages"
    input_patha = "./JPEGImages"
    xml_pathb = "./Annotations"
    xml_patha = "./Annotations"
    new_output_jpg = './output_mixup_jpg'    
    new_output_xml = './output_mixup_xml'
    if not os.path.exists(new_output_jpg):
        os.mkdir(new_output_jpg)
    if not os.path.exists(new_output_xml):
        os.mkdir(new_output_xml)
    mixup_with_xml(input_patha,input_pathb,xml_patha, xml_pathb,new_output_jpg, new_output_xml)


  1. mosaic
import random
import cv2
import os
import glob
import numpy as np
from PIL import Image
from lxml import etree
# from ipdb import set_trace

OUTPUT_SIZE = (1024, 1024)  # Height, Width
SCALE_RANGE = (0.5, 0.5)
FILTER_TINY_SCALE = 1 / 50 
# voc格式的数据集,anno_dir是标注xml文件,img_dir是对应jpg图片
ANNO_DIR = 'JPEGImages'
IMG_DIR = 'Annotations'
# category_name = ['background', 'person']
def main():
    img_paths, annos = get_dataset(ANNO_DIR, IMG_DIR)
    print(img_paths, annos)
    for i in range(1, 30, 1):
        idxs = random.sample(range(len(annos)), 4)  # 从annos列表长度中随机取4个数
        # set_trace()

        new_image, new_annos = update_image_and_anno(img_paths, annos,
                                                    idxs,
                                                    OUTPUT_SIZE, SCALE_RANGE,
                                                    filter_scale=FILTER_TINY_SCALE)
        # 更新获取新图和对应anno
        img_output_folder = "./img_mos/"
        if not os.path.exists(img_output_folder):
            os.mkdir(img_output_folder)
        img_name = 'mosic_20220814_{}.jpg'.format(i)
        img_path = img_output_folder + img_name
        cv2.imwrite(img_path, new_image)
        # annos是
        result_list = []
        for anno in new_annos:
            start_point = (int(anno[1] * OUTPUT_SIZE[1]), int(anno[2] * OUTPUT_SIZE[0]))  # 左上角点
            end_point = (int(anno[3] * OUTPUT_SIZE[1]), int(anno[4] * OUTPUT_SIZE[0]))  # 右下角点
            result = [anno[0], 1, int(anno[1] * OUTPUT_SIZE[1]), int(anno[2] * OUTPUT_SIZE[0]), int(anno[3] * OUTPUT_SIZE[1]), int(anno[4] * OUTPUT_SIZE[0])]
            result_list.append(result)
            cv2.rectangle(new_image, start_point, end_point, (0, 255, 0), 1, cv2.LINE_AA)  # 每循环一次在合成图画一个矩形

        xml_output_folder = "./xml_mos/"
        if not os.path.exists(xml_output_folder):
            os.mkdir(xml_output_folder)
        if (xml_output_folder is not None) and (os.path.exists(xml_output_folder)):
            output_xml(result_list, img_name, new_image.shape, os.path.join(xml_output_folder, img_name.split('.')[0]+".xml"))
    

        cv2.imwrite('wind_output_box.jpg', new_image)

        new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB)
        new_image = Image.fromarray(new_image.astype(np.uint8))
        i = i + 1
        # new_image.show()
        # cv2.imwrite('./img/wind_output111.jpg', new_image)


def update_image_and_anno(all_img_list, all_annos, idxs, output_size, scale_range, filter_scale=0.):
    output_img = np.zeros([output_size[0], output_size[1], 3], dtype=np.uint8)
    scale_x = scale_range[0] + random.random() * (scale_range[1] - scale_range[0])
    scale_y = scale_range[0] + random.random() * (scale_range[1] - scale_range[0])
    divid_point_x = int(scale_x * output_size[1])
    divid_point_y = int(scale_y * output_size[0])

    new_anno = []
    for i, idx in enumerate(idxs):
        # set_trace()
        path = all_img_list[idx]
        img_annos = all_annos[idx]

        img = cv2.imread(path)
        if i == 0:  # top-left
            img = cv2.resize(img, (divid_point_x, divid_point_y))
            output_img[:divid_point_y, :divid_point_x, :] = img
            for bbox in img_annos:
                xmin = bbox[1] * scale_x
                ymin = bbox[2] * scale_y
                xmax = bbox[3] * scale_x
                ymax = bbox[4] * scale_y
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])

        elif i == 1:  # top-right
            img = cv2.resize(img, (output_size[1] - divid_point_x, divid_point_y))
            output_img[:divid_point_y, divid_point_x:output_size[1], :] = img
            for bbox in img_annos:
                xmin = scale_x + bbox[1] * (1 - scale_x)
                ymin = bbox[2] * scale_y
                xmax = scale_x + bbox[3] * (1 - scale_x)
                ymax = bbox[4] * scale_y
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])
        elif i == 2:  # bottom-left
            img = cv2.resize(img, (divid_point_x, output_size[0] - divid_point_y))
            output_img[divid_point_y:output_size[0], :divid_point_x, :] = img
            for bbox in img_annos:
                xmin = bbox[1] * scale_x
                ymin = scale_y + bbox[2] * (1 - scale_y)
                xmax = bbox[3] * scale_x
                ymax = scale_y + bbox[4] * (1 - scale_y)
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])
        else:  # bottom-right
            img = cv2.resize(img, (output_size[1] - divid_point_x, output_size[0] - divid_point_y))
            output_img[divid_point_y:output_size[0], divid_point_x:output_size[1], :] = img
            for bbox in img_annos:
                xmin = scale_x + bbox[1] * (1 - scale_x)
                ymin = scale_y + bbox[2] * (1 - scale_y)
                xmax = scale_x + bbox[3] * (1 - scale_x)
                ymax = scale_y + bbox[4] * (1 - scale_y)
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])

    return output_img, new_anno


def get_dataset(anno_dir, img_dir):
    # class_id = category_name.index('person')

    img_paths = []
    annos = [] 
    # for anno_file in glob.glob(os.path.join(anno_dir, '*.txt')):
    for anno_file in glob.glob(os.path.join(anno_dir, '*.xml')):
       # print(anno_file)
        anno_id = anno_file.split('/')[-1].split('.')[0]
        #img_name = anno_id + '.jpg'
        #anno_id = anno_file.split('\\')[-1].split('x')[0]
        # set_trace()

        # with open(anno_file, 'r') as f:
        #     num_of_objs = int(f.readline())

        # set_trace()
        img_path = os.path.join(img_dir, f'{anno_id}.jpg')
        print(img_path)

        img = cv2.imread(img_path)
        # set_trace()
        img_height, img_width, _ = img.shape
        del img

        boxes = []
        bnd_box = parseXmlFiles(anno_file)
       
        #print(bnd_box)
        for bnd_id, box in enumerate(bnd_box):
            # set_trace()
            # result = (box[0], 1, box[1],box[2], box[3], box[4])

            categories_id = box[0]

            xmin = max(int(box[1]), 0) / img_width

            ymin = max(int(box[2]), 0) / img_height

            xmax = min(int(box[3]), img_width) / img_width

            ymax = min(int(box[4]), img_height) / img_height

            boxes.append([categories_id, xmin, ymin, xmax, ymax])


            if not boxes:
                continue
        # result_list.append(result)
        img_paths.append(img_path)
        annos.append(boxes)
    #print(result_list,6666666)
    print("annos:所有对原图缩放后的坐标:", annos)
    print(img_paths)
    return img_paths, annos


def parseXmlFiles(anno_dir):
    tree = etree.parse(anno_dir)
    root = tree.getroot()
    objectes = root.findall('.//object')
    bnd_box = []
    for object in objectes:
        name = object.find("name").text

        bndbox = object.find("bndbox")
        xmin = float(bndbox.find("xmin").text)
        xmax = float(bndbox.find("xmax").text)
        ymin = float(bndbox.find("ymin").text)
        ymax = float(bndbox.find("ymax").text)

        # bnd_box.append([name, xmin, xmax, ymin, ymax])
        bnd_box.append([name, xmin, ymin, xmax, ymax])
        # print(len(bnd_box),bnd_box)
    return bnd_box


def output_xml(result_list, src_img_name,img_shape, xml_path):
    """output result to xml

    Args:
        result_list (list): [ (code,score,xmin,ymin,xmax,ymax), ]
        src_img_name (str): source image name.
        img_shape(list): img_shape
        xml_path: xml path
    Returns:
        None
    """
    if 0 == len(result_list):
        return None
    xml_fmt = '''<annotation>
<folder>VOC2007</folder>
<filename>{:}</filename>
<size>
<width>{:d}</width>
<height>{:d}</height>
<depth>{:d}</depth>
</size>
<objectsum>{:d}</objectsum>
{:}</annotation>'''

    object_fmt = '''<object>
<Serial>{:d}</Serial>
<name>{:}</name>
<bndbox>
<xmin>{:d}</xmin>
<ymin>{:d}</ymin>
<xmax>{:d}</xmax>
<ymax>{:d}</ymax>
</bndbox>
</object>'''
    
    h,w,c = img_shape
    objects_str = ""
    for inx, res in enumerate(result_list):
        item_str = object_fmt.format(
            (inx + 1),
            res[0],
            int(res[2]),
            int(res[3]),
            int(res[4]),
            int(res[5])
            )
        objects_str = objects_str + item_str
    xml_str = xml_fmt.format(
        src_img_name,
        w,
        h,
        c,
        len(result_list),
        objects_str
    )
    with open(xml_path, "w") as outfile:
        outfile.write(xml_str)


if __name__ == '__main__':
    main()


import random

import cv2
import os
import glob
import numpy as np
from PIL import Image
from lxml import etree
import random
import requests
from io import BytesIO
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
import xml.etree.ElementTree as ET
from xml.etree.ElementTree import Element
import gflags
import sys
 
 
def aHash(img):
    # 均值哈希算法
    # 缩放为8*8
    img = cv2.resize(img, (8, 8))
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # s为像素和初值为0,hash_str为hash值初值为''
    s = 0
    hash_str = ''
    # 遍历累加求像素和
    for i in range(8):
        for j in range(8):
            s = s+gray[i, j]
    # 求平均灰度
    avg = s/64
    # 灰度大于平均值为1相反为0生成图片的hash值
    for i in range(8):
        for j in range(8):
            if gray[i, j] > avg:
                hash_str = hash_str+'1'
            else:
                hash_str = hash_str+'0'
    return hash_str
 
 
def dHash(img):
    # 差值哈希算法
    # 缩放8*8
    img = cv2.resize(img, (9, 8))
    # 转换灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    hash_str = ''
    # 每行前一个像素大于后一个像素为1,相反为0,生成哈希
    for i in range(8):
        for j in range(8):
            if gray[i, j] > gray[i, j+1]:
                hash_str = hash_str+'1'
            else:
                hash_str = hash_str+'0'
    return hash_str
 
 
def pHash(img):
    # 感知哈希算法
    # 缩放32*32
    img = cv2.resize(img, (32, 32))   # , interpolation=cv2.INTER_CUBIC
 
    # 转换为灰度图
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    # 将灰度图转为浮点型,再进行dct变换
    dct = cv2.dct(np.float32(gray))
    # opencv实现的掩码操作
    dct_roi = dct[0:8, 0:8]
 
    hash = []
    avreage = np.mean(dct_roi)
    for i in range(dct_roi.shape[0]):
        for j in range(dct_roi.shape[1]):
            if dct_roi[i, j] > avreage:
                hash.append(1)
            else:
                hash.append(0)
    return hash
 
 
def calculate(image1, image2):
    # 灰度直方图算法
    # 计算单通道的直方图的相似值
    hist1 = cv2.calcHist([image1], [0], None, [256], [0.0, 255.0])
    hist2 = cv2.calcHist([image2], [0], None, [256], [0.0, 255.0])
    # 计算直方图的重合度
    degree = 0
    for i in range(len(hist1)):
        if hist1[i] != hist2[i]:
            degree = degree + \
                (1 - abs(hist1[i] - hist2[i]) / max(hist1[i], hist2[i]))
        else:
            degree = degree + 1
    degree = degree / len(hist1)
    return degree
 
 
def classify_hist_with_split(image1, image2, size=(256, 256)):
    # RGB每个通道的直方图相似度
    # 将图像resize后,分离为RGB三个通道,再计算每个通道的相似值
    image1 = cv2.resize(image1, size)
    image2 = cv2.resize(image2, size)
    sub_image1 = cv2.split(image1)
    sub_image2 = cv2.split(image2)
    sub_data = 0
    for im1, im2 in zip(sub_image1, sub_image2):
        sub_data += calculate(im1, im2)
    sub_data = sub_data / 3
    return sub_data
 
 
def cmpHash(hash1, hash2):
    # Hash值对比
    # 算法中1和0顺序组合起来的即是图片的指纹hash。顺序不固定,但是比较的时候必须是相同的顺序。
    # 对比两幅图的指纹,计算汉明距离,即两个64位的hash值有多少是不一样的,不同的位数越小,图片越相似
    # 汉明距离:一组二进制数据变成另一组数据所需要的步骤,可以衡量两图的差异,汉明距离越小,则相似度越高。汉明距离为0,即两张图片完全一样
    n = 0
    # hash长度不同则返回-1代表传参出错
    if len(hash1) != len(hash2):
        return -1
    # 遍历判断
    for i in range(len(hash1)):
        # 不相等则n计数+1,n最终为相似度
        if hash1[i] != hash2[i]:
            n = n + 1
    return n
 
 
def getImageByUrl(url):
    # 根据图片url 获取图片对象
    html = requests.get(url, verify=False)
    image = Image.open(BytesIO(html.content))
    return image
 
 
def PILImageToCV():
    # PIL Image转换成OpenCV格式
    path = "/Users/waldenz/Documents/Work/doc/TestImages/t3.png"
    img = Image.open(path)
    plt.subplot(121)
    plt.imshow(img)
    print(isinstance(img, np.ndarray))
    img = cv2.cvtColor(np.asarray(img), cv2.COLOR_RGB2BGR)
    print(isinstance(img, np.ndarray))
    plt.subplot(122)
    plt.imshow(img)
    plt.show()
 
 
def CVImageToPIL():
    # OpenCV图片转换为PIL image
    path = "/Users/waldenz/Documents/Work/doc/TestImages/t3.png"
    img = cv2.imread(path)
    # cv2.imshow("OpenCV",img)
    plt.subplot(121)
    plt.imshow(img)
 
    img_b = Image.fromarray(cv2.cvtColor(img, cv2.COLOR_BGR2RGB))
    plt.subplot(122)
    plt.imshow(img_b)
    plt.show()
 
def bytes_to_cvimage(filebytes):
    # 图片字节流转换为cv image
    image = Image.open(filebytes)
    img = cv2.cvtColor(np.asarray(image), cv2.COLOR_RGB2BGR)
    return img
 
def runAllImageSimilaryFun(img_a, img_b):
    # 均值、差值、感知哈希算法三种算法值越小,则越相似,相同图片值为0
    # 三直方图算法和单通道的直方图 0-1之间,值越大,越相似。 相同图片为1
 
    # t1,t2   14;19;10;  0.70;0.75
    # t1,t3   39 33 18   0.58 0.49
    # s1,s2  7 23 11     0.83 0.86  挺相似的图片
    # c1,c2  11 29 17    0.30 0.31
 
    # if para1.startswith("http"):
    #      # 根据链接下载图片,并转换为opencv格式
    #     img_a = getImageByUrl(para1)
    #     img_a = cv2.cvtColor(np.asarray(img_a), cv2.COLOR_RGB2BGR)
 
    #     img_b = getImageByUrl(para2)
    #     img_b = cv2.cvtColor(np.asarray(img_b), cv2.COLOR_RGB2BGR)
    # else:
    #     # 通过imread方法直接读取物理路径
    #     img_a = cv2.imread(para1)
    #     img_b = cv2.imread(para2)
 
    hash1 = aHash(img_a)
    hash2 = aHash(img_b)
    n1 = cmpHash(hash1, hash2)
    n1 = 1-float(n1/64)
    # print('均值哈希算法相似度aHash:', n1)
 
    hash1 = dHash(img_a)
    hash2 = dHash(img_b)
    n2 = cmpHash(hash1, hash2)
    n2 = 1 - float(n2/64)
    # print('差值哈希算法相似度dHash:', n2)
 
    hash1 = pHash(img_a)
    hash2 = pHash(img_b)
    n3 = cmpHash(hash1, hash2)
    n3 = 1-float(n3/64)
    # print('感知哈希算法相似度pHash:', n3)
 
    n4 = classify_hist_with_split(img_a, img_b)
    n4 = round(n4[0], 2)
    # print('三直方图算法相似度:', n4)
 
    n5 = calculate(img_a, img_b)
    n5 = n5[0]
    # print("单通道的直方图", n5)
    # print("%d %d %d %.2f %.2f " % (n1, n2, n3, round(n4[0], 2), n5[0]))
    # print("%.2f %.2f %.2f %.2f %.2f " % (1-float(n1/64), 1 -
    #                                      float(n2/64), 1-float(n3/64), round(n4[0], 2), n5[0]))
    
    print(n1,n2,n3,n4,n5)
    print(min(n1,n2,n3,n4,n5))
    return min(n1,n2,n3,n4,n5)

OUTPUT_SIZE = (600, 600)  # Height, Width
SCALE_RANGE = (0.5, 0.5)
FILTER_TINY_SCALE = 1 / 50  # if height or width lower than this scale, drop it.

# voc格式的数据集,anno_dir是标注xml文件,img_dir是对应jpg图片
ANNO_DIR = 'Annotations'
IMG_DIR = 'JPEGImages'

# category_name = ['background', 'person']


def main():
    img_paths, annos = get_dataset(ANNO_DIR, IMG_DIR)
    print(img_paths, annos,66666666666666666666666666666666666666666666)

    for i in range(1, 1600, 1):
        idxs = random.sample(range(len(annos)), 4)  # 从annos列表长度中随机取4个数
        # print(idxs,111111111111)
        # set_trace()
        # idxs = [i for i in annos]
        new_image, new_annos = update_image_and_anno(img_paths, annos,
                                                    idxs,
                                                    OUTPUT_SIZE, SCALE_RANGE,
                                                    filter_scale=FILTER_TINY_SCALE)
        # 更新获取新图和对应anno
        img_output_folder = "./augment_1207/mosic_jpg/"
        if not os.path.exists(img_output_folder):
            os.mkdir(img_output_folder)
        img_name = '{}.jpg'.format(str(idxs[0])+'_'+str(idxs[1])+'_'+str(idxs[2])+'_'+str(idxs[3]))
        img_path = img_output_folder + img_name
        cv2.imwrite(img_path, new_image)
        # annos是
        result_list = []
        for anno in new_annos:
            start_point = (int(anno[1] * OUTPUT_SIZE[1]), int(anno[2] * OUTPUT_SIZE[0]))  # 左上角点
            end_point = (int(anno[3] * OUTPUT_SIZE[1]), int(anno[4] * OUTPUT_SIZE[0]))  # 右下角点
            result = [anno[0], 1, int(anno[1] * OUTPUT_SIZE[1]), int(anno[2] * OUTPUT_SIZE[0]), int(anno[3] * OUTPUT_SIZE[1]), int(anno[4] * OUTPUT_SIZE[0])]
            result_list.append(result)
            cv2.rectangle(new_image, start_point, end_point, (0, 255, 0), 1, cv2.LINE_AA)  # 每循环一次在合成图画一个矩形

        xml_output_folder = "./augment_1207/mosic_xml/"
        if not os.path.exists(xml_output_folder):
            os.mkdir(xml_output_folder)
        if (xml_output_folder is not None) and (os.path.exists(xml_output_folder)):
            output_xml(result_list, img_name, new_image.shape, os.path.join(xml_output_folder, img_name.split('.')[0]+".xml"))
    

        cv2.imwrite('wind_output_box.jpg', new_image)

        new_image = cv2.cvtColor(new_image, cv2.COLOR_BGR2RGB)
        new_image = Image.fromarray(new_image.astype(np.uint8))
        i = i + 1
        # new_image.show()
        # cv2.imwrite('./img/wind_output111.jpg', new_image)


def update_image_and_anno(all_img_list, all_annos, idxs, output_size, scale_range, filter_scale=0.):
    output_img = np.zeros([output_size[0], output_size[1], 3], dtype=np.uint8)
    scale_x = scale_range[0] + random.random() * (scale_range[1] - scale_range[0])
    scale_y = scale_range[0] + random.random() * (scale_range[1] - scale_range[0])
    divid_point_x = int(scale_x * output_size[1])
    divid_point_y = int(scale_y * output_size[0])

    new_anno = []
    for i, idx in enumerate(idxs):
        # set_trace()
        path = all_img_list[idx]
        img_annos = all_annos[idx]

        img = cv2.imread(path)
        if i == 0:  # top-left
            img = cv2.resize(img, (divid_point_x, divid_point_y))
            output_img[:divid_point_y, :divid_point_x, :] = img
            for bbox in img_annos:
                xmin = bbox[1] * scale_x
                ymin = bbox[2] * scale_y
                xmax = bbox[3] * scale_x
                ymax = bbox[4] * scale_y
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])

        elif i == 1:  # top-right
            img = cv2.resize(img, (output_size[1] - divid_point_x, divid_point_y))
            output_img[:divid_point_y, divid_point_x:output_size[1], :] = img
            for bbox in img_annos:
                xmin = scale_x + bbox[1] * (1 - scale_x)
                ymin = bbox[2] * scale_y
                xmax = scale_x + bbox[3] * (1 - scale_x)
                ymax = bbox[4] * scale_y
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])
        elif i == 2:  # bottom-left
            img = cv2.resize(img, (divid_point_x, output_size[0] - divid_point_y))
            output_img[divid_point_y:output_size[0], :divid_point_x, :] = img
            for bbox in img_annos:
                xmin = bbox[1] * scale_x
                ymin = scale_y + bbox[2] * (1 - scale_y)
                xmax = bbox[3] * scale_x
                ymax = scale_y + bbox[4] * (1 - scale_y)
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])
        else:  # bottom-right
            img = cv2.resize(img, (output_size[1] - divid_point_x, output_size[0] - divid_point_y))
            output_img[divid_point_y:output_size[0], divid_point_x:output_size[1], :] = img
            for bbox in img_annos:
                xmin = scale_x + bbox[1] * (1 - scale_x)
                ymin = scale_y + bbox[2] * (1 - scale_y)
                xmax = scale_x + bbox[3] * (1 - scale_x)
                ymax = scale_y + bbox[4] * (1 - scale_y)
                new_anno.append([bbox[0], xmin, ymin, xmax, ymax])

    return output_img, new_anno


def get_dataset(anno_dir, img_dir):
    # class_id = category_name.index('person')

    img_paths = []
    annos = [] 
    # for anno_file in glob.glob(os.path.join(anno_dir, '*.txt')):
    for anno_file in glob.glob(os.path.join(anno_dir, '*.xml')):
       # print(anno_file)
        anno_id = anno_file.split('/')[-1].split('.')[0]
        #img_name = anno_id + '.jpg'
        #anno_id = anno_file.split('\\')[-1].split('x')[0]
        # set_trace()

        # with open(anno_file, 'r') as f:
        #     num_of_objs = int(f.readline())

        # set_trace()
        img_path = os.path.join(img_dir, f'{anno_id}.jpg')
        print(img_path)

        img = cv2.imread(img_path)
        # set_trace()
        img_height, img_width, _ = img.shape
        del img

        boxes = []
        bnd_box = parseXmlFiles(anno_file)
       
        #print(bnd_box)
        for bnd_id, box in enumerate(bnd_box):
            # set_trace()
            # result = (box[0], 1, box[1],box[2], box[3], box[4])

            categories_id = box[0]

            xmin = max(int(box[1]), 0) / img_width

            ymin = max(int(box[2]), 0) / img_height

            xmax = min(int(box[3]), img_width) / img_width

            ymax = min(int(box[4]), img_height) / img_height

            boxes.append([categories_id, xmin, ymin, xmax, ymax])


            if not boxes:
                continue
        # result_list.append(result)
        img_paths.append(img_path)
        annos.append(boxes)
    #print(result_list,6666666)
    print("annos:所有对原图缩放后的坐标:", annos)
    print(img_paths)
    return img_paths, annos


def prettyXml(element, indent, newline, level=0):  
    if element:  
        if element.text == None or element.text.isspace():  
            element.text = newline + indent * (level + 1)
        else:
            element.text = newline + indent * (level + 1) + element.text.strip() + newline + indent * (level + 1)
    temp = list(element)  
    for subelement in temp:
        if temp.index(subelement) < (len(temp) - 1): 
            subelement.tail = newline + indent * (level + 1)
        else: 
            subelement.tail = newline + indent * level
        prettyXml(subelement, indent, newline, level=level + 1)  


def parseXmlFiles(anno_dir):
    tree = etree.parse(anno_dir)
    root = tree.getroot()
    objectes = root.findall('.//object')
    bnd_box = []
    for object in objectes:
        name = object.find("name").text

        bndbox = object.find("bndbox")
        xmin = float(bndbox.find("xmin").text)
        xmax = float(bndbox.find("xmax").text)
        ymin = float(bndbox.find("ymin").text)
        ymax = float(bndbox.find("ymax").text)

        # bnd_box.append([name, xmin, xmax, ymin, ymax])
        bnd_box.append([name, xmin, ymin, xmax, ymax])
        # print(len(bnd_box),bnd_box)
    return bnd_box


def output_xml(result_list, src_img_name,img_shape, xml_path):
    """output result to xml

    Args:
        result_list (list): [ (code,score,xmin,ymin,xmax,ymax), ]
        src_img_name (str): source image name.
        img_shape(list): img_shape
        xml_path: xml path
    Returns:
        None
    """
    if 0 == len(result_list):
        return None
    xml_fmt = '''<annotation>
<folder>VOC2007</folder>
<filename>{:}</filename>
<size>
<width>{:d}</width>
<height>{:d}</height>
<depth>{:d}</depth>
</size>
<objectsum>{:d}</objectsum>
{:}</annotation>'''

    object_fmt = '''<object>
<Serial>{:d}</Serial>
<name>{:}</name>
<bndbox>
<xmin>{:d}</xmin>
<ymin>{:d}</ymin>
<xmax>{:d}</xmax>
<ymax>{:d}</ymax>
</bndbox>
</object>'''
    
    h,w,c = img_shape
    objects_str = ""
    for inx, res in enumerate(result_list):
        item_str = object_fmt.format(
            (inx + 1),
            res[0],
            int(res[2]),
            int(res[3]),
            int(res[4]),
            int(res[5])
            )
        objects_str = objects_str + item_str
    xml_str = xml_fmt.format(
        src_img_name,
        w,
        h,
        c,
        len(result_list),
        objects_str
    )
    with open(xml_path, "w") as outfile:
        outfile.write(xml_str)


if __name__ == '__main__':
    main()



  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值