• [技术干货] 学习 Python 之 Pygame 开发坦克大战(五)-转载
     坦克大战完善地图 我的素材放到了百度网盘里,里面还有原版坦克大战素材,我都放在一起来,我的素材是从原版改的,各位小伙伴可以直接用或者自己改一下再用,做出适合自己的素材  素材链接:百度网盘 链接:https://pan.baidu.com/s/19sCyH7rp37f6DzRj0iXDCA?pwd=tkdz 提取码:tkdz  那我们就继续编写坦克大战吧  1. 创建砖墙 坦克大战中,砖墙是最常见的墙,子弹都可以轻松击穿,下面我们来加入到自己的坦克大战中  创建砖墙类  import pygame.image from ParentObject import ParentObject  class BrickWall(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Wall/BrickWall.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect) 在主类中加入砖墙列表  class MainGame:     ...     # 砖墙     brickWallList = []     ... 在主类中加入初始化砖墙函数和显示砖墙函数  def drawBrickWall(self, brickWallList):     for brickWall in brickWallList:         if brickWall.isDestroy:             brickWallList.remove(brickWall)         else:             brickWall.draw(MainGame.window)  def initBrickWall(self):     for i in range(20):         MainGame.brickWallList.append(BrickWall(i * 25, 200)) 这里我在y = 200的位置,连续画出20个砖,砖的图片是25x25的,所以为了防止重叠,要间隔25个距离(像素)  在主函数startGame()函数中调用函数  def startGame(self):     # 初始化展示模块     pygame.display.init()     # 设置窗口大小     size = (SCREEN_WIDTH, SCREEN_HEIGHT)     # 初始化窗口     MainGame.window = pygame.display.set_mode(size)     # 设置窗口标题     pygame.display.set_caption('Tank Battle')      # 初始化我方坦克     MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)      # 播放开始音乐     MainGame.startingSound.play()          # 初始化场景     self.initBrickWall()      while 1:         # 设置背景颜色         MainGame.window.fill(BACKGROUND_COLOR)          # 获取窗口事件         self.getPlayingModeEvent()                  # 显示物体         self.drawBrickWall(MainGame.brickWallList)          # 展示敌方坦克         self.drawEnemyTank()          # 显示我方坦克         MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])          # 我方坦克移动         if not MainGame.playerTank.stop:             MainGame.playerTank.move()             MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)          # 显示我方坦克子弹         self.drawPlayerBullet(MainGame.playerBulletList)          # 展示敌方坦克子弹         self.drawEnemyBullet()          # 展示爆炸效果         self.drawExplode()          # 更新窗口         pygame.display.update()  运行一下,看看结果  但是墙只是摆设,子弹可以穿过,坦克也可以穿过,下面给墙增加碰撞效果  2. 给砖墙增加子弹击中的碰撞效果 在子弹类中增加函数  def bulletCollideBrickWall(self, brickWallList, explodeList):     for brickWall in brickWallList:         # 子弹与墙发生碰撞         if pygame.sprite.collide_rect(self, brickWall):             self.isDestroy = True             brickWall.isDestroy = True             # 碰撞出现爆炸效果             explode = Explode(brickWall, 25)             explodeList.append(explode)             # 出现爆炸播放音效             Sound('../Sound/block.wav').play() 在主函数中调用 修改显示子弹的两个函数  def drawPlayerBullet(self, playerBulletList):     # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除     for bullet in playerBulletList:         if not bullet.isDestroy:             bullet.draw(MainGame.window)             bullet.move(MainGame.explodeList)             bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)             bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)         else:             playerBulletList.remove(bullet) def drawEnemyBullet(self):     for bullet in MainGame.enemyTankBulletList:         if not bullet.isDestroy:             bullet.draw(MainGame.window)             bullet.move(MainGame.explodeList)             bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)             bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)         else:             bullet.source.bulletCount -= 1             MainGame.enemyTankBulletList.remove(bullet) 运行一下看看  可以看到墙可以被打掉了  3. 给砖墙添加坦克不能通过的碰撞效果 在敌方坦克类中加入函数,在我方坦克类中加入函数 collideBrickWall()  def collideBrickWall(self, brickWallList):     for brickWall in brickWallList:         if pygame.sprite.collide_rect(self, brickWall):             self.rect.left = self.prvX             self.rect.top = self.prvY 在主类中调用 在while循环中调用  while 1:     # 设置背景颜色     MainGame.window.fill(BACKGROUND_COLOR)      # 获取窗口事件     self.getPlayingModeEvent()      # 显示物体     self.drawBrickWall(MainGame.brickWallList)      # 展示敌方坦克     self.drawEnemyTank()      # 显示我方坦克     MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])      # 我方坦克移动     if not MainGame.playerTank.stop:         MainGame.playerTank.move()         MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)         # 不能撞墙         MainGame.playerTank.collideBrickWall(MainGame.brickWallList) 在主类的drawEnemyTank()中调用  def drawEnemyTank(self):     ...     for tank in MainGame.enemyTankList:         # 坦克还有生命值         if tank.life > 0:             tank.draw(MainGame.window)             tank.move()             tank.collidePlayerTank(MainGame.playerTank)             tank.collideEnemyTank(MainGame.enemyTankList)             # 不能撞墙             tank.collideBrickWall(MainGame.brickWallList)             bullet = tank.shot()             if bullet is not None:                 MainGame.enemyTankBulletList.append(bullet)         # 坦克生命值为0,就从列表中剔除         else:             MainGame.enemyTankCurrentCount -= 1             MainGame.enemyTankList.remove(tank)  运行一下,看看效果  确实是不能穿过了 那就完成啦,接下来就是添加其他的物体了 添加的过程跟添加砖墙是一样的   4. 添加石墙 创建石墙类  import pygame.image from ParentObject import ParentObject  class StoneWall(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Wall/StoneWall.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect) 在主类中加入石墙列表 在主类中加入显示石墙函数  def initStoneWall(self):     for i in range(20):         MainGame.stoneWallList.append(StoneWall(i * 25, 400))          def drawStoneWall(self, stoneWallList):     for stoneWall in stoneWallList:         if stoneWall.isDestroy:             stoneWallList.remove(stoneWall)         else:             stoneWall.draw(MainGame.window) 给石墙添加坦克不能通过的碰撞效果 在敌方坦克类中加入函数,在我方坦克类中加入函数 collideStoneWall()  def collideStoneWall(self, stoneWallList):     for stoneWall in stoneWallList:         if pygame.sprite.collide_rect(self, stoneWall):             self.rect.left = self.prvX             self.rect.top = self.prvY 在主类中调用函数  接下来是给子弹添加打击石墙的效果  def bulletCollideStoneWall(self, stoneWallList, explodeList):     for stoneWall in stoneWallList:         if pygame.sprite.collide_rect(self, stoneWall):             # 判断坦克的等级,大于等于2时,可以打穿石墙             if self.source.level >= 2:                 stoneWall.isDestroy = True             self.isDestroy = True             explode = Explode(stoneWall, 25)             explodeList.append(explode)             Sound('../Sound/block.wav').play() 在主类中调用函数  主类的完整代码  import pygame import sys  from PlayerTank import PlayerTank from EnemyTank import EnemyTank from Sound import Sound from BrickWall import BrickWall from StoneWall import StoneWall  SCREEN_WIDTH = 1100 SCREEN_HEIGHT = 600 BACKGROUND_COLOR = pygame.Color(0, 0, 0) FONT_COLOR = (255, 255, 255) PLAYER_TANK_POSITION = (325, 550)  class MainGame:      # 窗口Surface对象     window = None      # 玩家坦克     playerTank = None      # 玩家子弹     playerBulletList = []     playerBulletNumber = 3      # 敌人坦克     enemyTankList = []     enemyTankTotalCount = 5     # 用来给玩家展示坦克的数量     enemyTankCurrentCount = 5      # 敌人坦克子弹     enemyTankBulletList = []      # 爆炸列表     explodeList = []      # 坦克移动音效     playerTankMoveSound = Sound('../Sound/player.move.wav').setVolume()      # 游戏开始音效     startingSound = Sound('../Sound/intro.wav')      # 砖墙     brickWallList = []     # 石墙     stoneWallList = []      def __init__(self):         pass      def startGame(self):         # 初始化展示模块         pygame.display.init()         # 设置窗口大小         size = (SCREEN_WIDTH, SCREEN_HEIGHT)         # 初始化窗口         MainGame.window = pygame.display.set_mode(size)         # 设置窗口标题         pygame.display.set_caption('Tank Battle')          # 初始化我方坦克         MainGame.playerTank = PlayerTank(PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1], 1, 1)          # 播放开始音乐         MainGame.startingSound.play()          # 初始化场景         self.initBrickWall()         self.initStoneWall()          while 1:             # 设置背景颜色             MainGame.window.fill(BACKGROUND_COLOR)              # 获取窗口事件             self.getPlayingModeEvent()              # 显示物体             self.drawBrickWall(MainGame.brickWallList)             self.drawStoneWall(MainGame.stoneWallList)              # 展示敌方坦克             self.drawEnemyTank()              # 显示我方坦克             MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])              # 我方坦克移动             if not MainGame.playerTank.stop:                 MainGame.playerTank.move()                 MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)                 MainGame.playerTank.collideBrickWall(MainGame.brickWallList)                 MainGame.playerTank.collideStoneWall(MainGame.stoneWallList)              # 显示我方坦克子弹             self.drawPlayerBullet(MainGame.playerBulletList)              # 展示敌方坦克子弹             self.drawEnemyBullet()              # 展示爆炸效果             self.drawExplode()              # 更新窗口             pygame.display.update()                  def getPlayingModeEvent(self):         # 获取所有事件         eventList = pygame.event.get()         for event in eventList:              if event.type == pygame.QUIT:                 sys.exit()              """             stop属性用来控制坦克移动,当键盘按键按下时,坦克可以移动,一直按住一直移动,当按键抬起时,停止移动             如果没有该属性,按一下按键移动一次,按一下移动一下,不能一直按住一直移动             """             if event.type == pygame.KEYDOWN:                 MainGame.playerTankMoveSound.play(-1)                 if event.key == pygame.K_w:                     MainGame.playerTank.direction = 'UP'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_s:                     MainGame.playerTank.direction = 'DOWN'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_a:                     MainGame.playerTank.direction = 'LEFT'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_d:                     MainGame.playerTank.direction = 'RIGHT'                     MainGame.playerTank.stop = False                 elif event.key == pygame.K_j:                     # 判断子弹数量是否超过指定的个数                     if len(MainGame.playerBulletList) < MainGame.playerBulletNumber:                         bullet = MainGame.playerTank.shot()                         MainGame.playerBulletList.append(bullet)                         # 添加音效                         Sound('../Sound/shoot.wav').play(0)              if event.type == pygame.KEYUP:                 MainGame.playerTankMoveSound.stop()                 if event.key == pygame.K_w:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_s:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_a:                     MainGame.playerTank.stop = True                 elif event.key == pygame.K_d:                     MainGame.playerTank.stop = True      def drawPlayerBullet(self, playerBulletList):         # 遍历整个子弹列表,如果是没有被销毁的状态,就把子弹显示出来,否则从列表中删除         for bullet in playerBulletList:             if not bullet.isDestroy:                 bullet.draw(MainGame.window)                 bullet.move(MainGame.explodeList)                 bullet.playerBulletCollideEnemyTank(MainGame.enemyTankList, MainGame.explodeList)                 bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)                 bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList)             else:                 playerBulletList.remove(bullet)      def drawEnemyTank(self):         # 如果当前坦克为0,那么就该重新生成坦克         if len(MainGame.enemyTankList) == 0:             # 一次性产生三个,如果剩余坦克数量超过三,那只能产生三个             n = min(3, MainGame.enemyTankTotalCount)             # 如果最小是0,就说明敌人坦克没有了,那么就赢了             if n == 0:                 print('赢了')                 return             # 没有赢的话,就产生n个坦克             self.initEnemyTank(n)             # 总个数减去产生的个数             MainGame.enemyTankTotalCount -= n         # 遍历坦克列表,展示坦克并且移动         for tank in MainGame.enemyTankList:             # 坦克还有生命值             if tank.life > 0:                 tank.draw(MainGame.window)                 tank.move()                 tank.collidePlayerTank(MainGame.playerTank)                 tank.collideEnemyTank(MainGame.enemyTankList)                 tank.collideBrickWall(MainGame.brickWallList)                 tank.collideStoneWall(MainGame.stoneWallList)                 bullet = tank.shot()                 if bullet is not None:                     MainGame.enemyTankBulletList.append(bullet)             # 坦克生命值为0,就从列表中剔除             else:                 MainGame.enemyTankCurrentCount -= 1                 MainGame.enemyTankList.remove(tank)          def initEnemyTank(self, number):         y = 0         position = [0, 425, 850]         index = 0         for i in range(number):             x = position[index]             enemyTank = EnemyTank(x, y)             MainGame.enemyTankList.append(enemyTank)             index += 1      def drawEnemyBullet(self):         for bullet in MainGame.enemyTankBulletList:             if not bullet.isDestroy:                 bullet.draw(MainGame.window)                 bullet.move(MainGame.explodeList)                 bullet.enemyBulletCollidePlayerTank(MainGame.playerTank, MainGame.explodeList)                 bullet.bulletCollideBrickWall(MainGame.brickWallList, MainGame.explodeList)                 bullet.bulletCollideStoneWall(MainGame.stoneWallList, MainGame.explodeList)             else:                 bullet.source.bulletCount -= 1                 MainGame.enemyTankBulletList.remove(bullet)      def drawExplode(self):         for e in MainGame.explodeList:             if e.isDestroy:                 MainGame.explodeList.remove(e)             else:                 e.draw(MainGame.window)      def drawBrickWall(self, brickWallList):         for brickWall in brickWallList:             if brickWall.isDestroy:                 brickWallList.remove(brickWall)             else:                 brickWall.draw(MainGame.window)      def initBrickWall(self):         for i in range(20):             MainGame.brickWallList.append(BrickWall(i * 25, 200))      def initStoneWall(self):         for i in range(20):             MainGame.stoneWallList.append(StoneWall(i * 25, 400))      def drawStoneWall(self, stoneWallList):         for stoneWall in stoneWallList:             if stoneWall.isDestroy:                 stoneWallList.remove(stoneWall)             else:                 stoneWall.draw(MainGame.window)  if __name__ == '__main__':     MainGame().startGame()  5. 添加玩家基地 坦克大战是玩家坦克在保护自己基地的同时消灭敌方坦克,当玩家坦克生命值为0或者基地爆炸时,游戏失败,下面来添加玩家的基地  创建基地类  import pygame.image  from ParentObject import ParentObject  class Home(ParentObject):     def __init__(self, x, y):         super().__init__()         self.image = pygame.image.load('../Image/Home/Home.png')         self.rect = self.image.get_rect()         self.rect.left = x         self.rect.top = y         self.isDestroy = False      def draw(self, window):         window.blit(self.image, self.rect)  为基地添加碰撞效果,在两个坦克类中加入下面的函数  def collideHome(self, home):     if pygame.sprite.collide_rect(self, home):         self.rect.left = self.prvX         self.rect.top = self.prvY 在主函数创建基地变量,并初始化和调用上面的函数  之后给基地加入子弹击中效果  def bulletCollidePlayerHome(self, home, explodeList):     if pygame.sprite.collide_rect(self, home):         self.isDestroy = True         explode = Explode(home, 50)         explodeList.append(explode)         Sound('../Sound/buh.wav').play()         return True     else:         return False 返回值用来判断是否结束游戏 在主类中设置一个变量记录是否游戏结束  def __init__(self):     # 初始化     MainGame.home = Home(425, 550)      # 记录是否输了     self.isDefeated = False 在循环中检查  while 1:     ...     # 检查是否输了     if self.isDefeated:         self.defeated()         break     ... def defeated(self):     # 失败了坦克不能移动了     MainGame.playerTankMoveSound.stop()     # 播放失败音乐     Sound('../Sound/gameOver.wav').play()     print('游戏结束')     self.isDefeated = True 游戏结束后要改变窗口中的内容,显示你输了,所以要用break跳出  这里需要使用到在窗口显示文字,编写一个函数  def drawText(self, text, x, y, fontSize, window):     # 初始化字体     pygame.font.init()     font = pygame.font.SysFont('georgia', fontSize)     # 加载文字并设置颜色     fontColor = pygame.Color(255, 255, 255)     fontObject = font.render(text, True, fontColor)     # 展示文字     window.blit(fontObject, (x, y)) 记得在主函数中调用  while 1:     # 设置背景颜色     MainGame.window.fill(BACKGROUND_COLOR)      # 获取窗口事件     self.getPlayingModeEvent()      # 显示物体     self.drawBrickWall(MainGame.brickWallList)     self.drawStoneWall(MainGame.stoneWallList)     MainGame.home.draw(MainGame.window)      # 展示敌方坦克     self.drawEnemyTank()      # 显示我方坦克     MainGame.playerTank.draw(MainGame.window, PLAYER_TANK_POSITION[0], PLAYER_TANK_POSITION[1])      # 我方坦克移动     if not MainGame.playerTank.stop:         MainGame.playerTank.move()         MainGame.playerTank.collideEnemyTank(MainGame.enemyTankList)         MainGame.playerTank.collideBrickWall(MainGame.brickWallList)         MainGame.playerTank.collideStoneWall(MainGame.stoneWallList)         MainGame.playerTank.collideHome(MainGame.home)      # 显示我方坦克子弹     self.drawPlayerBullet(MainGame.playerBulletList)      # 展示敌方坦克子弹     self.drawEnemyBullet()      # 展示爆炸效果     self.drawExplode()      # 检查是否输了     if self.isDefeated:         self.defeated()         break      # 更新窗口     pygame.display.update()  # 设置背景颜色 MainGame.window.fill(BACKGROUND_COLOR)  # 显示字体 self.drawText('Defeated', 200, 200, 50, MainGame.window)  # 更新窗口 pygame.display.update()  给玩家提示敌人坦克数量  到这里,坦克大战的基本功能就实现了,接下来就是添加其他的场景物体和坦克样子了  6. 最终效果 主界面,这里直接放了一张图片上去,图片在素材里,上面的坦克是自己画上去的,w和s键可以上下移动坦克,选择对应的模式  选择关卡,这里使用用了四张图片,左右箭头,上面的标题和start文字,这些都是图片,按下黄色箭头可以选择关卡,使用的鼠标事件   游戏界面   其中加入了奖励功能  地图制作可以使用excel读取信息,下面是第一关的地图   坦克大战代码  链接:https://pan.baidu.com/s/1qFV-0hi0cgZS1Hnvx6mK6Q?pwd=90tk 提取码:90tk ———————————————— 版权声明:本文为CSDN博主「_DiMinisH」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/qq_37354060/article/details/129110457 
  • [技术干货] python进阶——自动驾驶寻找车道-转载
      前言 本程序主要讲述python的AI视觉方面的应用:自动驾驶寻找车道。  推荐博客好文章 (上过csdn热榜top5的优质好文!)  1.若不知道怎么安装opencv或者使用的请看我的这篇文章(曾上过csdn综合热榜的top1):  python进阶——人工智能视觉识别_lqj_本人的博客-CSDN博客  2.基于opencv的人工智能视觉实现的目标实时跟踪功能(曾上过csdn综合热榜的top5):  python进阶——人工智能实时目标跟踪_lqj_本人的博客-CSDN博客  3.基于PaddlenHub模块以及playsound模块实现口罩检测并实时语音报警(曾上过csdn综合热榜的top1):  python进阶——AI视觉实现口罩检测实时语音报警系统_lqj_本人的博客-CSDN博客  项目前须知 1.opencv的图像灰度转化方法  gray = cv2.cvtColor("图像", cv2.COLOR_RGB2GRAY) 2.opencv检测图像边缘  高斯模糊图像  cv2.GaussianBlur(gray, (5, 5), 0) 获取精明图像  canny = cv2.Canny(blur, 50, 150) 3.matplotlib绘制图像库的使用  项目详情 我们先拿到实时摄像的某一帧的图像 导入库  import cv2 import numpy as np import matplotlib.pyplot as plt 边缘检测 进行图像的灰度转化以及图像的边缘检测  def canny(image):     """1.图像的灰度转化"""     #把某一帧的图片转换成灰度图像     gray = cv2.cvtColor(lane_image, cv2.COLOR_RGB2GRAY)     """2.检测图像边缘"""     #高斯模糊图像     blur = cv2.GaussianBlur(gray, (5, 5), 0)     #获取精明的图片     canny = cv2.Canny(blur, 50, 150)     return canny image = cv2.imread('1.jpg') lane_image = np.copy(image) canny = canny(lane_image) plt.imshow(canny) plt.show()  得到绘图结果    因为中国的车道时沿右边行驶的,所以我们可以在绘图的图像中清楚的看见X轴与Y轴的数码,由X轴的(400,0)位置到X轴的大约(1100,0)位置是右车道的宽度,然后我们再来看Y轴的数码,大约在150的位置是我们可视范围内的右车道的尽头点,又因为(400,0)到(1100,0)的距离为700px,所以我们可以得到可视范围内的右车道的尽头点为(700,150)。  根据上述位置的计算,我们可以得出一个右车道中的三角形  def region_of_interest(image):     height = image.shape[0]     polygons = np.array([         [(400,height),(1100,height),(700,150)]     ])     mask = np.zeros_like(image)     cv2.fillPoly(mask,polygons,255)     return mask   image = cv2.imread('1.jpg') lane_image = np.copy(image) canny = canny(lane_image) cv2.imshow('result',region_of_interest(canny)) cv2.waitKey(0) 得出检测三角形   生成蒙版  将检测到的图像由255(白色)表示,周围区域用0(黑色表示)    有时候三角形不是正好与我们看到的进到点到左右两侧点的形状正好相似,所以我们需要自己微调一下      polygons = np.array([         [(400,height),(1200,height),(800,200)]     ]) 然后,我们可以对我们的图像进行右车道三角形的裁剪      masked_image = cv2.bitwise_and(image,mask) cropped_image = region_of_interest(canny) cv2.imshow('result',cropped_image) 边缘检测与蒙版产生的效果 裁剪显示图像   定义车道起始点位置 def make_coordinates(image,line_parameters):     slope,intercept = line_parameters     print(image.shape)     y1 = image.shape[0]     y2 = int(y1*(3/5))     x1 = int((y1 - intercept)/slope)     x2 = int((y2 - intercept)/slope)     return np.array([x1,y1,x2,y2]) 霍夫变换的直线检测 用到的是Opencv封装好的函数cv.HoughLinesP函数,使用到的参数如下:  image:输入图像,通常为canny边缘检测处理后的图像 rho:线段以像素为单位的距离精度 theta:像素以弧度为单位的角度精度(np.pi/180较为合适) threshold:霍夫平面累加的阈值 minLineLength:线段最小长度(像素级) maxLineGap:最大允许断裂长度  lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5) 绘制车道 def display_lines(image,lines):     line_image = np.zeros_like(image)     if lines is not None:         for line in lines:             # print(line)             x1,y1,x2,y2 = line.reshape(4)             cv2.line(line_image,(x1,y1),(x2,y2),(255,100,10),10)     return line_image 效果图像    图像与绘制车道融合  视频流中位置检测   def average_slope_intercept(image,lines):     left_fit = []     right_fit = []     if lines is None:         return None     for line in lines:         x1,y1,x2,y2 = line.reshape(4)         parameters = np.polyfit((x1,x2),(y1,y2),1)         # print(parameters)         slope = parameters[0]         intercept = parameters[1]         if slope < 0:             left_fit.append((slope,intercept))         else:             right_fit.append((slope,intercept))             print(left_fit)             print(right_fit)  打印左右位置结果    检测数每一帧的左右位置结果      left_fit_average = np.average(left_fit,axis=0)     right_fit_average = np.average(right_fit,axis=0)     print(left_fit_average,'左')     print(right_fit_average,'右')     left_line = make_coordinates(image,left_fit_average)     right_line = make_coordinates(image,right_fit_average)     return np.array([left_line,right_line])  导入视频流做最后处理 cap = cv2.VideoCapture('3.mp4')   # try: while cap.isOpened():         _,frame = cap.read()           canny_image = canny(frame)           cropped_image = region_of_interest(canny_image)           lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)           averaged_lines = average_slope_intercept(frame, lines)           line_image = display_lines(frame, averaged_lines)           combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)           # cv2.resizeWindow("result", 1080, 960);           cv2.imshow('result', line_image)           cv2.waitKey(10)  完整代码 import cv2 import numpy as np import matplotlib.pyplot as plt   def make_coordinates(image,line_parameters):     slope,intercept = line_parameters     print(image.shape)     y1 = image.shape[0]     y2 = int(y1*(3/5))     x1 = int((y1 - intercept)/slope)     x2 = int((y2 - intercept)/slope)     return np.array([x1,y1,x2,y2])   def average_slope_intercept(image,lines):     left_fit = []     right_fit = []     if lines is None:         return None     for line in lines:         x1,y1,x2,y2 = line.reshape(4)         parameters = np.polyfit((x1,x2),(y1,y2),1)         # print(parameters)         slope = parameters[0]         intercept = parameters[1]         if slope < 0:             left_fit.append((slope,intercept))         else:             right_fit.append((slope,intercept))             # print(left_fit)             # print(right_fit)     left_fit_average = np.average(left_fit,axis=0)     right_fit_average = np.average(right_fit,axis=0)     print(left_fit_average,'左')     print(right_fit_average,'右')     left_line = make_coordinates(image,left_fit_average)     right_line = make_coordinates(image,right_fit_average)     return np.array([left_line,right_line])   def canny(image):     """1.图像的灰度转化"""     #把某一帧的图片转换成灰度图像     gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)     """2.检测图像边缘"""     #高斯模糊图像     blur = cv2.GaussianBlur(gray, (5, 5), 0)     #获取精明的图片     canny = cv2.Canny(blur, 50, 150)     return canny #每一行都是一个二维数组,包含我们的线坐标,形式为[[x1,yl,x2,y2]]。这些坐标指定了线条的参数,以及线条相对与图像空间位置,确保他们被放置在正确的位置 def display_lines(image,lines):     line_image = np.zeros_like(image)     if lines is not None:         for line in lines:             # print(line)             x1,y1,x2,y2 = line.reshape(4)             cv2.line(line_image,(x1,y1),(x2,y2),(255,100,10),10)     return line_image   def region_of_interest(image):     height = image.shape[0]     polygons = np.array([     [(300,height),(650,height),(500,150)]     ])     mask = np.zeros_like(image)     cv2.fillPoly(mask,polygons,255)     masked_image = cv2.bitwise_and(image,mask)     return masked_image   # image = cv2.imread('1.png') # lane_image = np.copy(image) # canny_image = canny(lane_image) # cropped_image = region_of_interest(canny_image) # lines = cv2.HoughLinesP(cropped_image,2,np.pi/180,100,np.array([]),minLineLength=40,maxLineGap=5) # averaged_lines = average_slope_intercept(lane_image,lines) # line_image = display_lines(lane_image,averaged_lines) # combo_image = cv2.addWeighted(lane_image,0.8,line_image,1,1) # cv2.imshow('result',combo_image) # cv2.waitKey(0)     cap = cv2.VideoCapture('3.mp4')   # try: while cap.isOpened():         _,frame = cap.read()           canny_image = canny(frame)           cropped_image = region_of_interest(canny_image)           lines = cv2.HoughLinesP(cropped_image, 2, np.pi/180, 100, np.array([]), minLineLength=40, maxLineGap=5)           averaged_lines = average_slope_intercept(frame, lines)           line_image = display_lines(frame, averaged_lines)           combo_image = cv2.addWeighted(frame, 0.8, line_image, 1, 1)           # cv2.resizeWindow("result", 1080, 960);           cv2.imshow('result', combo_image)           cv2.waitKey(10)  用前须知 根据自己的需要适当微调参数:  def region_of_interest(image):     height = image.shape[0]     polygons = np.array([     [(300,height),(650,height),(500,150)]     ])     mask = np.zeros_like(image)     cv2.fillPoly(mask,polygons,255)     masked_image = cv2.bitwise_and(image,mask)     return masked_image 效果显示  ———————————————— 版权声明:本文为CSDN博主「lqj_本人」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lbcyllqj/article/details/128937913 
  • [技术干货] Python雪花代码
     一.什么是python Python由荷兰数学和计算机科学研究学会的吉多·范罗苏姆于1990年代初设计,作为一门叫做ABC语言的替代品。   Python提供了高效的高级数据结构,还能简单有效地面向对象编程。Python语法和动态类型,以及解释型语言的本质,使它成为多数平台上写脚本和快速开发应用的编程语言, [ 随着版本的不断更新和语言新功能的添加,逐渐被用于独立的、大型项目的开发。  Python解释器易于扩展,可以使用C语言或C++(或者其他可以通过C调用的语言)扩展新的功能和数据类型。Python也可用于可定制化软件中的扩展程序语言。Python丰富的标准库,提供了适用于各个主要系统平台的源码或机器码  二.游戏代码效果呈现    三.游戏主代码 ''' Function:     炸弹人小游戏 ''' import sys import cfg import random import pygame from modules import *  '''游戏主程序''' def main(cfg):     # 初始化     pygame.init()     pygame.mixer.init()     pygame.mixer.music.load(cfg.BGMPATH)     pygame.mixer.music.play(-1, 0.0)     screen = pygame.display.set_mode(cfg.SCREENSIZE)     pygame.display.set_caption('炸弹人')     # 开始界面     Interface(screen, cfg, mode='game_start')     # 游戏主循环     font = pygame.font.SysFont('Consolas', 15)     for gamemap_path in cfg.GAMEMAPPATHS:         # -地图         map_parser = mapParser(gamemap_path, bg_paths=cfg.BACKGROUNDPATHS, wall_paths=cfg.WALLPATHS, blocksize=cfg.BLOCKSIZE)         # -水果         fruit_sprite_group = pygame.sprite.Group()         used_spaces = []         for i in range(5):             coordinate = map_parser.randomGetSpace(used_spaces)             used_spaces.append(coordinate)             fruit_sprite_group.add(Fruit(random.choice(cfg.FRUITPATHS), coordinate=coordinate, blocksize=cfg.BLOCKSIZE))         # -我方Hero         coordinate = map_parser.randomGetSpace(used_spaces)         used_spaces.append(coordinate)         ourhero = Hero(imagepaths=cfg.HEROZELDAPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='ZELDA')         # -电脑Hero         aihero_sprite_group = pygame.sprite.Group()         coordinate = map_parser.randomGetSpace(used_spaces)         aihero_sprite_group.add(Hero(imagepaths=cfg.HEROBATMANPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='BATMAN'))         used_spaces.append(coordinate)         coordinate = map_parser.randomGetSpace(used_spaces)         aihero_sprite_group.add(Hero(imagepaths=cfg.HERODKPATHS, coordinate=coordinate, blocksize=cfg.BLOCKSIZE, map_parser=map_parser, hero_name='DK'))         used_spaces.append(coordinate)         # -炸弹bomb         bomb_sprite_group = pygame.sprite.Group()         # -用于判断游戏胜利或者失败的flag         is_win_flag = False         # -主循环         screen = pygame.display.set_mode(map_parser.screen_size)         clock = pygame.time.Clock()         while True:             dt = clock.tick(cfg.FPS)             for event in pygame.event.get():                 if event.type == pygame.QUIT:                     pygame.quit()                     sys.exit(-1)                 # --↑↓←→键控制上下左右, 空格键丢炸弹                 elif event.type == pygame.KEYDOWN:                     if event.key == pygame.K_UP:                         ourhero.move('up')                     elif event.key == pygame.K_DOWN:                         ourhero.move('down')                     elif event.key == pygame.K_LEFT:                         ourhero.move('left')                     elif event.key == pygame.K_RIGHT:                         ourhero.move('right')                     elif event.key == pygame.K_SPACE:                         if ourhero.bomb_cooling_count <= 0:                             bomb_sprite_group.add(ourhero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))             screen.fill(cfg.WHITE)             # --电脑Hero随机行动             for hero in aihero_sprite_group:                 action, flag = hero.randomAction(dt)                 if flag and action == 'dropbomb':                     bomb_sprite_group.add(hero.generateBomb(imagepath=cfg.BOMBPATH, digitalcolor=cfg.YELLOW, explode_imagepath=cfg.FIREPATH))             # --吃到水果加生命值(只要是Hero, 都能加)             ourhero.eatFruit(fruit_sprite_group)             for hero in aihero_sprite_group:                 hero.eatFruit(fruit_sprite_group)             # --游戏元素都绑定到屏幕上             map_parser.draw(screen)             for bomb in bomb_sprite_group:                 if not bomb.is_being:                     bomb_sprite_group.remove(bomb)                 explode_area = bomb.draw(screen, dt, map_parser)                 if explode_area:                     # --爆炸火焰范围内的Hero生命值将持续下降                     if ourhero.coordinate in explode_area:                         ourhero.health_value -= bomb.harm_value                     for hero in aihero_sprite_group:                         if hero.coordinate in explode_area:                             hero.health_value -= bomb.harm_value             fruit_sprite_group.draw(screen)             for hero in aihero_sprite_group:                 hero.draw(screen, dt)             ourhero.draw(screen, dt)             # --左上角显示生命值             pos_x = showText(screen, font, text=ourhero.hero_name+'(our):'+str(ourhero.health_value), color=cfg.YELLOW, position=[5, 5])             for hero in aihero_sprite_group:                 pos_x, pos_y = pos_x+15, 5                 pos_x = showText(screen, font, text=hero.hero_name+'(ai):'+str(hero.health_value), color=cfg.YELLOW, position=[pos_x, pos_y])             # --我方玩家生命值小于等于0/电脑方玩家生命值均小于等于0则判断游戏结束             if ourhero.health_value <= 0:                 is_win_flag = False                 break             for hero in aihero_sprite_group:                 if hero.health_value <= 0:                     aihero_sprite_group.remove(hero)             if len(aihero_sprite_group) == 0:                 is_win_flag = True                 break             pygame.display.update()             clock.tick(cfg.FPS)         if is_win_flag:             Interface(screen, cfg, mode='game_switch')         else:             break     Interface(screen, cfg, mode='game_end')  '''run''' if __name__ == '__main__':     while True:         main(cfg)  四.cfg '''配置文件''' import os  '''屏幕大小''' SCREENSIZE = (640, 480) '''块大小''' BLOCKSIZE = 30 '''FPS''' FPS = 30 '''游戏地图路径''' GAMEMAPPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/maps/1.map', 'resources/maps/2.map']] '''墙路径''' WALLPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/misc/wall0.png', 'resources/images/misc/wall1.png', 'resources/images/misc/wall2.png']] '''英雄路径''' HERODKPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/dk/left.png', 'resources/images/dk/right.png', 'resources/images/dk/up.png', 'resources/images/dk/down.png']] HEROZELDAPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/zelda/left.png', 'resources/images/zelda/right.png', 'resources/images/zelda/up.png', 'resources/images/zelda/down.png']] HEROBATMANPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/batman/left.png', 'resources/images/batman/right.png', 'resources/images/batman/up.png', 'resources/images/batman/down.png']] '''水果路径''' FRUITPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/misc/banana.png', 'resources/images/misc/cherry.png']] '''背景路径''' BACKGROUNDPATHS = [os.path.join(os.getcwd(), path) for path in \     ['resources/images/misc/bg0.png', 'resources/images/misc/bg1.png', 'resources/images/misc/bg2.png']] '''爆炸和发射路径''' BOMBPATH = os.path.join(os.getcwd(), 'resources/images/misc/bomb.png') FIREPATH = os.path.join(os.getcwd(), 'resources/images/misc/fire.png') '''背景音乐''' BGMPATH = os.path.join(os.getcwd(), 'resources/audio/bgm.mp3') '''一些颜色''' YELLOW = (255, 255, 0) BLUE = (0, 0, 255) RED = (255, 0, 0) BLACK = (0, 0, 0) WHITE = (255, 255, 255)  五.README # Introduction https://mp.weixin.qq.com/s/XzB_cJMFEtz6p_MvqiaCrA  # Environment ``` OS: Windows10 Python: Python3.5+(have installed necessary dependencies) ```  # Usage ``` Step1: pip install -r requirements.txt Step2: run "python Game19.py" ```  # Game Display ![giphy](demonstration/running.gif)  六.requirements pygame ———————————————— 版权声明:本文为CSDN博主「小刘在C站」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/lzl10211345/article/details/128989934 
  • [常见FAQ] 请问判题器Debug模式的正确使用姿势?
    请问python怎么使用判题器的调试模式?我已经按照以下步骤进行:1. Robot参数使用-d2. 选手程序中在初始化时候sleep一段时间3. 使用pycharm attach到robot_gui.exe的进程但是pycharm出现报错:搜索引擎找不到相关解决方案,只能来求助各位了ORZ
  • [区域初赛赛题问题] 想咨询下大家Linux版本的run_keyboard_demo遇到的问题
    一直提示无keyboard这个module,但我已经检查环境下使用的python均已安装这个module。只有使用判题器时,找不到这个module,不知道这个判题器是如何调用python解释器的。
  • [赋能学习] Pyhive连接MRS集群HIVE
    1 安装Python环境1.1 安装Miniconda conda是一个开源的包、环境管理器,可以用于在同一个机器上安装不同Python版本的软件包及其依赖,并能够在不同的Python环境之间切换,Anaconda包括Conda、Python以及一大堆安装好的工具包,比如:numpy、pandas等,Miniconda包括Conda、Python。 此处,我们不需要如此多的工具包,故选择MiniConda。1)下载Miniconda(Python3版本)下载地址:cid:link_0 2)安装Miniconda (1)执行以下命令进行安装,并按照提示操作,直到安装完成。bash Miniconda3-py38_23.1.0-1-Linux-x86_64.sh在安装过程中,出现以下提示时,可以指定安装路径 出现以下字样,即为安装完成 3)加载环境变量配置文件,使之生效source ~/.bashrc4)取消激活base环境Miniconda安装完成后,每次打开终端都会激活其默认的base环境,我们可通过以下命令,禁止激活默认base环境。 conda config --set auto_activate_base false1.2 创建Python3.6以上环境conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free conda config --add channels https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main conda config --set show_channel_urls yes2)创建Python环境conda create --name superset python=3.8 说明:conda环境管理常用命令创建环境:conda create -n env_name查看所有环境:conda info --envs删除一个环境:conda remove -n env_name --all1.3 适配环境下载相关依赖进入Miniconda3所在目录下bin执行 ./pip3 install pyhive==0.6.1 --force-reinstall ./pip3 install thrift==0.16.0 --force-reninstall ./pip3 install thrift-sasl==0.4.3 ./pip3 install pure-sasl==0.6.2 ./pip3 install sasl==0.3.修改源代码,将域名写死 vim /opt/miniconda3/lib/python3.8/site-packages/pyhive/hive.py添加kerberos_service_host参数 1.4 通过python代码连接hive./python3import os from pyhive import hive host='x.x.x.x' port=21066 auth='KERBEROS' kerberos_service_name='hive' kerberos_service_host='hadoop.hadoop.com' os.system('source /opt/140client/bigdata_env') os.system('echo password | kinit user') with hive.connect(host=host, port=port, auth=auth, kerberos_service_host=kerberos_service_host, kerberos_service_name=kerberos_service_name) as conn: with conn.cursor() as cur: cur.execute("show tables") for i in cur.fetchall(): print(i)注:host是hive对应实例节点,需提前在页面查看然后填写查看Hive数据库中表
  • [热门活动] 不仅有干货,还有问题的答案,还在等什么,快来看了 。
     codeArts2月份技术干货合集以及数据库版块问题合集。 1.pytest中的fixture基本用法【转】 https://bbs.huaweicloud.com/forum/thread-0234112932818513063-1-1.html  2.java double 类型_关于Java中的double类型数据【转】 https://bbs.huaweicloud.com/forum/thread-0222111742558810011-1-1.html  3.解决 Maven ‘parent.relativePath‘ of POM【转】 https://bbs.huaweicloud.com/forum/thread-0236112434845316028-1-1.html  4.Non-resolvable parent POM for解决【转】 https://bbs.huaweicloud.com/forum/thread-0220112499223799035-1-1.html  5.在Maven中出现Could not find artifact ...:pom:0.0.1-SNAPSHOT and ‘parent.relativePath‘的错误怎么解决?【转】 https://bbs.huaweicloud.com/forum/thread-0267112499546748034-1-1.html  6.Unable to start ServletWebServerApplicationContext due to missing ServletWebServerFactory bean【转】 https://bbs.huaweicloud.com/forum/thread-0221112501396435024-1-1.html  7.Python利用plotly绘制正二十面体详解【转】 https://bbs.huaweicloud.com/forum/thread-0275112930670884059-1-1.html  8.基于Python实现绘制一个足球【转】 https://bbs.huaweicloud.com/forum/thread-0261112931071459060-1-1.html  9.python __init__与 __new__的区别【转】 https://bbs.huaweicloud.com/forum/thread-0234112931373944060-1-1.html  10.详解Flask数据库的连接与使用【转】 https://bbs.huaweicloud.com/forum/thread-0221112931454173048-1-1.html  11.tensorflow1.x和tensorflow2.x中的tensor转换为字符串的实现【转】 https://bbs.huaweicloud.com/forum/thread-0261112931688113061-1-1.html  12.Flask中特殊装饰器的使用【转】 https://bbs.huaweicloud.com/forum/thread-0237112931865991052-1-1.html  13.pytorch 简介及常用工具包展示【转】 https://bbs.huaweicloud.com/forum/thread-0236112932234100050-1-1.html  14.Pytorch中的 torch.distributions库详解【转】 https://bbs.huaweicloud.com/forum/thread-0234112932425200062-1-1.html  数据库版块问题合集 1.【GaussDB】连接高斯数据库建议使用什么工具? https://bbs.huaweicloud.com/forum/thread-0220111983015871012-1-1.html  2.【GaussDB】数据库存入空字符串会全部被转成NULL,这个能控制不转吗? https://bbs.huaweicloud.com/forum/thread-0236111894276100005-1-1.html  3.【GaussDB】 GaussDB create sequence有if not exists 的类似写法吗 https://bbs.huaweicloud.com/forum/thread-0237111825559668004-1-1.html  4.【GaussDB】连接高斯数据库建议使用什么工具? https://bbs.huaweicloud.com/forum/thread-0220111983015871012-1-1.html  5.【GaussDB】报错: "ERROR:query returened no rows when process into context",怎么处理? https://bbs.huaweicloud.com/forum/thread-0261111825433614001-1-1.html  
  • [技术干货] pytest中的fixture基本用法【转】
    简介:  fixture区别于unnitest的传统单元测试(setup/teardown)有显著改进:  1.有独立的命名,并通过声明它们从测试函数、模块、类或整个项目中的使用来激活。  2.按模块化的方式实现,每个fixture都可以互相调用。  3.fixture的范围从简单的单元测试到复杂的功能测试,可以对fixture配置参数,或者跨函数function,类class,模块module或整个测试session范围。fixture的功能fixture是pytest特有的功能,用以在测试执行前和执行后进行必要的准备和清理工作。使用pytest.fixture标识,定义在函数前面。在你编写测试函数的时候,你可以将此函数名称做为传入参数,pytest将会以依赖注入方式,将该函数的返回值作为测试函数的传入参数。主要的目的是为了提供一种可靠和可重复性的手段去运行那些最基本的测试内容。从功能上看来,与setup、teardown相似,但是优势明显:命名方式灵活,不局限于setup和teardown这几个命名conftest.py 配置里可以实现数据共享,不需要import就能自动找到一些配置scope="module" 每一个.py文件调用一次scope="session" 可以实现多个.py跨文件使用一个session来完成多个用例特点及优势1、命令灵活:对于setup.teardown,可以不起这两个名字2、数据共享:在conftest.py配置里写的方法可以实现数据共享,不需要import导入,可以跨文件共享3、scope的层次及神奇的yield组合相当于各种setup和teardown4、实现参数化基本用法@pytest.fixture()import pytest @pytest.fixture() def login():     print("完成登录操作") def test_search():     print("搜索功能,此方法不需要完成登录即可执行") def test_cart(login):     print("加入购物车,需要完成登录才可以")fixture在自动化中的应用--作用域@pytest.fixture(scope='module')取值范围说明function函数级每个函数或方法都会调用class类级别每个测试类只运行一次module模块级别每一个.py文件只调用一次package包级没一个python包至调用一次session会话级每次会话只需要运行一次,会话内所有方法及类、模块都共享这个方法import pytest @pytest.fixture(scope='module') def login():     print("完成登录操作") def test_search(login):     print("搜索功能,此方法不需要完成登录即可执行") def test_cart(login):     print("加入购物车,需要完成登录才可以")、fixture在自动化中的应用-yield关键字场景:你已经可以将测试方法【前要执行的或依赖的】解决了,测试方法后销毁清除数据的要如何进行呢?解决:通过在fixture函数中加入yield关键字,yield是调用第一次返回结果,第二次执行他下面的语句返回。步骤:在@pytest.fixture(scope=module),在登录的方法中加yield,之后加销毁清楚的步骤。import pytest @pytest.fixture(scope='module') def login():     # setup操作     print("完成登录操作")     token = 1     yield token  # 相当于return的操作     # teardown操作     print("完成登出操作")   def test_search(login):     # print("搜索功能,此方法不需要完成登录即可执行")     print(f"token = {login}")   def test_cart(login):     # print("加入购物车,需要完成登录才可以")     print(f"token = {login}")fixture在自动化中的应用--数据共享场景:与其他测试工程师合作一起开发时,公共的模块要在不同的文件中,要在大家都能访问到的地方解决:使用conftest.py这个文件进行数据共享,并且他可以放在不同位置骑着不同的范围共享作用前提:conftest文件名是不能换的放在项目下是全局的数据共享的地方执行:系统执行到参数login时,先从本模块中查找是否有这个名字的变量之后在conftest.py中找是否有步骤:将登录模块带@pytest.fixture写在conftest.py中fixture在自动化中的应用-自动应用场景:不想原测试方法有任何改动,或全部都自动实现自动应用,没特例,也都不需要返回值时可以选择自动应用解决:使用fixture中参数autouse=True实现步骤:在方法上面加@pytest.fixture(autouse=True)fixture在自动化中的应用-参数化场景:测试离不开数据,为了数据灵活,一般数据都是用过参数传的解决:fixture通过固定参数requests传递步骤:在fixture中增加@pytest.fixture(params=[1,2,3,'tom'])在方法参数写request,方法体里面使用request.param接收参数import pytest @pytest.fixture(params=[1, 2, 3, "测试"]) def login(request):     print(f"数据名称为:{request.param}")     return request.param def test_search(login):     print(f"{login}")
  • [技术干货] Pytorch中的 torch.distributions库详解【转】
    Pytorch torch.distributions库包介绍torch.distributions包包含可参数化的概率分布和采样函数。 这允许构建用于优化的随机计算图和随机梯度估计器。不可能通过随机样本直接反向传播。 但是,有两种主要方法可以创建可以反向传播的代理函数。这些是评分函数估计量 score function estimato似然比估计量 likelihood ratio estimatorREINFORCE路径导数估计量 pathwise derivative estimatorREINFORCE 通常被视为强化学习中策略梯度方法的基础,路径导数估计器常见于变分自编码器的重新参数化技巧中。虽然评分函数只需要样本 f(x)的值,但路径导数需要导数 f'(x)。本文重点讲解Pytorch中的 torch.distributions库。pytorch 的 torch.distributions 中可以定义正态分布:import torch from torch.distributions import  Normal mean=torch.Tensor([0,2]) normal=Normal(mean,1)sample()就是直接在定义的正太分布(均值为mean,标准差std是1)上采样:result = normal.sample() print("sample():",result)输出:sample(): tensor([-1.3362,  3.1730])rsample()不是在定义的正太分布上采样,而是先对标准正太分布 N(0,1) 进行采样,然后输出: mean + std × 采样值result = normal.rsample() print("rsample():",result)输出:rsample: tensor([ 0.0530,  2.8396])log_prob(value) 是计算value在定义的正态分布(mean,1)中对应的概率的对数,正太分布概率密度函数是:对其取对数可得:这里我们通过对数概率还原其对应的真实概率:print("result log_prob:",normal.log_prob(result).exp())输出:result log_prob: tensor([ 0.1634,  0.2005])
  • [技术干货] pytorch 简介及常用工具包展示【转】
    一、pytorch 简介Pytorch是torch的python版本,是由Facebook开源的神经网络框架,专门针对 GPU 加速的深度神经网络(DNN)编程。Torch 是一个经典的对多维矩阵数据进行操作的张量(tensor )库,在机器学习和其他数学密集型应用有广泛应用。Pytorch的计算图是动态的,可以根据计算需要实时改变计算图。由于Torch语言采用 Lua,导致在国内一直很小众,并逐渐被支持 Python 的 Tensorflow 抢走用户。作为经典机器学习库 Torch 的端口,PyTorch 为 Python 语言使用者提供了舒适的写代码选择。二、pytorch 优势1.简洁:PyTorch的设计追求最少的封装,尽量避免重复造轮子。不像 TensorFlow 中充斥着session、graph、operation、name_scope、variable、tensor、layer等全新的概念,PyTorch 的设计遵循tensor→variable(autograd)→nn.Module 三个由低到高的抽象层次,分别代表高维数组(张量)、自动求导(变量)和神经网络(层/模块),而且这三个抽象之间联系紧密,可以同时进行修改和操作。2.速度:PyTorch 的灵活性不以速度为代价,在许多评测中,PyTorch 的速度表现胜过 TensorFlow和Keras 等框架。3.易用:PyTorch 是所有的框架中面向对象设计的最优雅的一个。PyTorch的面向对象的接口设计来源于Torch,而Torch的接口设计以灵活易用而著称,Keras作者最初就是受Torch的启发才开发了Keras。4.活跃的社区:PyTorch 提供了完整的文档,循序渐进的指南,作者亲自维护的论坛,供用户交流和求教问题。Facebook 人工智能研究院对 PyTorch 提供了强力支持。三、pytorch 常用工具包torch :类似 NumPy 的张量库,支持GPU;torch.autograd :基于 type 的自动区别库,支持 torch 之中的所有可区分张量运行;torch.nn :为最大化灵活性而设计,与 autograd 深度整合的神经网络库;torch.optim:与 torch.nn 一起使用的优化包,包含 SGD、RMSProp、LBFGS、Adam 等标准优化方式;torch.multiprocessing: python 多进程并发,进程之间 torch Tensors 的内存共享;torch.utils:数据载入器。具有训练器和其他便利功能;torch.legacy(.nn/.optim) :出于向后兼容性考虑,从 Torch 移植来的 legacy 代码;四、pytorch 注意点特别注意一个问题:通道问题:不同视觉库对于图像读取的方式不一样,图像通道也不一样:opencv 的 imread 默认顺序时 H * W * Cpytorch的Tensor是 C * H * WTensorflow是两者都支持五、pytorch 理解numpy风格的tensor操作pytorch对tensor提供的API参照了numpy变量自动求导在计算过程形成的计算图中,参与的变量可快速计算出自己对于目标函数的梯度神经网络求导及损失函数优化等高层封装网络层封装在torch.nn损失函数封装在torch.functional优化函数封装在torch.optim六、pytorch-Tensor1. tensor 数据类型tensor数据类型:3浮点(float16,float32,float64)5整数(int16,int32,int64,int8+uint8)Data typedtypeCPU tensorGPU tensor16-bit floating pointtorch.float16 or torch.halftorch.HalfTensortorch.cuda.HalfTensor32-bit floating pointtorch.float32 or torch.floattorch.FloatTensortorch.cuda.FloatTensor64-bit floating pointtorch.float64 or torch.doubletorch.DoubleTensortorch.cuda.DoubleTensorData typedtypeCPU tensorGPU tensor8-bit integer(unsigned)torch.uint8torch.ByteTensortorch.cuda.ByteTensor8-bit integer(signed)torch.int8torch.CharTensortorch.cuda.CharTensor16-bit integer(signed)torch.int16 or torch.shorttorch.ShortTensortorch.cuda.ShortTensor32-bit integer(signed)torch.int32 or torch.inttorch.IntTensortorch.cuda.IntTensor64-bit integer(signed)torch.int64 or torch.longtorch.LongTensortorch.cuda.LongTensor2. 创建 tensor 相关的 API创建tensor的常见api方法名说明Tensor()直接从参数构造张量,支持list和numpy数组eye(row,column)创建指定行数&列数的单位tensor(单位阵)linspace(start,end,count)在[s,e]上创建c个元素的一维tensorlogspace(start,end,count)在[10s,10e]上创建c个元素的一维tensorones(size)返回指定shape的tensor,元素初始值为1zeros(size)返回指定shape的tensor,元素初始值为0ones_like(t)返回一个tensor,shape与t相同,且元素初始值为1zeros_like(t)返回一个tensor,shape与t相同,且元素初始值为1arange(s,e,sep)在区间[s,e)上以间隔sep生成一个序列张量3. tensor 对象的 APItensor 对象的方法方法名作用size()返回张量的shapenumel()计算tensor的元素个数view(shape)修改tensor的shape,与np.reshape相似,view返回的是对象的共享内存resize类似于view,但在size超出时会重新分配内存空间item若为单元素tensor,则返回python的scalarfrom_numpy从numpy数据填充numpy返回ndarray类型七、python 自动求导tensor对象通过一系列运算组成动态图,每个tensor对象都有以下几个控制求导的属性。变量作用requird_grad默认为False,表示变量是狗需要计算导数grad_fn变量的梯度函数grad变量对应的梯度八、pytorch 神经网络torch.nn提供了创建神经网络的基础构件,这些层都继承自Module类。下面是自己手动实现一个线性层(linear layer)。适当参考,以后直接调用现成的接口,这里稍微了解一下,无实际意义。 import torch  class Linear(torch.nn.Module):     def __init__(self, in_features, out_features, bias=True):         super(Linear, self).__init__()         # torch.randn() 返回一个符合均值为0,方差为1的正态分布         self.weight = torch.nn.Parameter(torch.randn(out_features, in_features))         if bias:             self.bias = torch.nn.Parameter(torch.randn(out_features))      def forward(self, x):         # xW+b         x = x.mm(self.weight)         if self.bias:             x = x + self.bias.expand_as(x)         return x  if __name__ == '__main__':          net = Linear(3,2)     x = net.forward     print('11',x) 下面表格中列出了比较重要的神经网络层组件。对应的在nn.functional模块中,提供这些层对应的函数实现。通常对于可训练参数的层使用module,而对于不需要训练参数的层如softmax这些,可以使用functional中的函数。一些容器:容器类型功能Module神经网络模块基类Sequential序贯模型,类似keras,用于构建序列型神经网络ModuleList用于存储层,不接受输入Parameters(t)模块的属性,用于保存其训练参数ParameterList参数列表1容器代码: # 方法1 像 model1 = nn.Sequential() model.add_module('fc1', nn.Linear(3,4)) model.add_module('fc2', nn.Linear(4,2)) model.add_module('output', nn.Softmax(2))  # 方法2 model2 = nn.Sequential(           nn.Conv2d(1,20,5),           nn.ReLU(),           nn.Conv2d(20,64,5),           nn.ReLU()         ) # 方法3         model3 = nn.ModuleList([nn.Linear(3,4), nn.ReLU(), nn.Linear(4,2)]) torch.nn.Module提供了神经网络的基类,当实现神经网络时需要继承自此模块,并在初始化函数中创建网络需要包含的层,并实现forward函数完成前向计算,网络的反向计算会由自动求导机制处理。通常将需要训练的层写在init函数中,将参数不需要训练的层在forward方法里调用对应的函数来实现相应的层。编码三步走:在pytorch中就只需要分三步:写好网络;编写数据的标签和路径索引;把数据送到网络。
  • [技术干货] Flask中特殊装饰器的使用【转】
    (1)@app.before_request请求到达视图函数之前,进行自定义操作,类似django中间件中的process_request,在app中使用则为全局,在蓝图中使用则针对当前蓝图注意正常状态下return值必须为None(2)@app.after_request响应返回到达客户端之前,进行自定义操作,类似jango中间件中的process_response,在app中使用则为全局,在蓝图中使用则针对当前蓝图注意正常状态下视图函数必须定义一个形参接收response对象,并通过return response返回(3)@app.errorhandler()错误状态码捕获执行函数,装饰器参数务必是4xx或者5xx的int型错误状态码(4) @app.template_global() :定义装饰全局模板可用的函数,直接可在模板中进行渲染使用@app.template_filter(): 定义装饰全局模板可用的过滤器函数,类似django中的自定义过滤器,直接可在模板中使用这两个特殊装饰器主要用在模板渲染!!!import apps from flask import request, session, redirect   app = apps.create_app()    @app.before_request def before1():     print("before1", request)    @app.before_request def before2():     print("before2")     if request.path == "/":         return None     else:         #这里抛出了一个异常,会被@app.errorhandler(Exception)         # 捕获到。         raise Exception("hahaha")    @app.before_request def before3():     print("before3")    @app.after_request def after1(res):     print("after1")     return res    @app.after_request def after2(res):     print("after2")     return res    @app.after_request def after3(res):     print("after3")     return res    # 处理异常,接受参数,可以重定向到指定页面 @app.errorhandler(Exception) def error(e):     print("error")     return redirect("/")    @app.route("/login") def login():     print("login")     return "login"   @app.route('/') def hello_world():  # put application's code here     return 'Hello World!'   if __name__ == '__main__':     app.run()
  • [技术干货] tensorflow1.x和tensorflow2.x中的tensor转换为字符串的实现【转】
    Tensorflow1.xTensorFlow 1.x 和 TensorFlow 2.x 的 API 存在很大差异,如果您想要将 TensorFlow 1.x 中的 tensor 格式转换成字符串,可以按照以下步骤进行:导入 TensorFlow 1.x 和其他必要的 Python 库。import tensorflow.compat.v1 as tf import numpy as np定义一个 TensorFlow 1.x 的 Tensor。例如:x = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32) 使用 tf.as_string() 方法将 Tensor 转换为字符串。例如:str_tensor = tf.as_string(x) 在 TensorFlow 1.x 中,Tensor 对象可以在 Session 中运行以获得实际的值。因此,在使用上述方法将 Tensor 转换为字符串后,需要在 Session 中运行以获得字符串值。with tf.Session() as sess:     str_tensor = sess.run(str_tensor) 在上面的例子中,我们使用了 TensorFlow 1.x 的 Session 来运行字符串 Tensor,最后 str_tensor 变量将包含 Tensor 的字符串表示形式。需要注意的是,在 TensorFlow 2.x 中,tf.as_string() 方法已经被 tf.strings.as_string() 方法所替代。同时,TensorFlow 2.x 中不需要使用 Session 来运行 Tensor 对象。Tensorflow2.x要将TensorFlow的Tensor格式转换为字符串,可以使用TensorFlow中的tf.strings方法。具体步骤如下:导入TensorFlow和其他必要的Python库。import tensorflow as tf import numpy as np 定义一个TensorFlow Tensor。例如:x = tf.constant([[1, 2, 3], [4, 5, 6]], dtype=tf.float32) 使用tf.strings.format()方法将Tensor转换为字符串。可以使用format()方法的模板字符串,将Tensor中的元素插入到字符串中。例如:str_tensor = tf.strings.format("Tensor: {}", x) 在上面的例子中,我们使用了"Tensor: {}"字符串作为模板,其中{}将被Tensor x中的元素替换。使用.numpy()方法将字符串Tensor转换为普通的Python字符串。例如:str_tensor = str_tensor.numpy().decode('utf-8') 在上面的例子中,我们首先使用.numpy()方法将Tensor转换为Numpy数组,然后使用.decode()方法将数组转换为UTF-8编码的字符串。最后,str_tensor变量将包含Tensor的字符串表示形式。
  • [技术干货] 详解Flask数据库的连接与使用【转】
    数据库连接配置HOST = "XXXXXXXXXXXXX" PORT = 3310 USERNAME = "root" PASSWORD = "@XXXXXXXXXXX" DATABASE = "mydb"   SQLALCHEMY_DATABASE_URI = f"mysql+pymysql://{USERNAME}:{quote(PASSWORD)}@{HOST}:{PORT}/{DATABASE}?charset=utf8mb4" SQLALCHEMY_TRACK_MODIFICATIONS = False SQLALCHEMY_ECHO = True 创建实体类from exts.DBServer import db from sqlalchemy import Column, Integer, String, Date, DateTime     class Article(db.Model):     __tablename__ = "article"     id = Column(Integer, primay_key=True, autoincrement=True)     title = Column(String(100), nullable=True)     pub_time = Column(DateTime, nullable=True)     author = Column(String(100), nullable=True)     content = Column(String(10000), nullable=True)     origin = Column(String(1000), nullable=True) controller:import json   from flask.blueprints import Blueprint from exts.DBServer import db from ..model.Article import Article from flask_sqlalchemy.query import Query from flask_restful import marshal from flask_restful import fields   article_bp = Blueprint("article", __name__, url_prefix="/article")   article_fields = {     "id": fields.Integer,     "title": fields.String,     "pub_time": fields.DateTime,     "author": fields.String,     "content": fields.String,     "origin": fields.String }     @article_bp.route("/queryAll") def queryAll():     query: Query = Article.query     articles = query.all()     article = query.get(1)     article2 = query.filter_by(author="XXX")     return json.dumps(marshal(articles, fields=article_fields),ensure_ascii=False) 配置打印SQL语句from exts.DBServer import db from sqlalchemy import Column, Integer, String     class User(db.Model):     __tablename__ = "user"     id = Column(Integer, primary_key=True, autoincrement=True)     username = Column(String(100), nullable=True)     password = Column(String(100), nullable=True)       def __repr__(self):         return "User %r" % self.body 或、与、非和排序@user_bp.route("/query") def query_match():     query: Query = User.query     result = query.filter(or_(User.username.contains("祥"), User.id == 1))       return json.dumps(marshal(result.all(), fields=user_fields), ensure_ascii=False)     @user_bp.route("/in") def in_sql():     query: Query = User.query     result = query.order_by(-User.password, -User.id)     return json.dumps(marshal(result.all(), fields=user_fields), ensure_ascii=False)
  • [技术干货] python __init__与 __new__的区别【转】
    一、构造函数 __init__ 与__new____new__   作用: 创建对象,并分配内存__init__ 作用: 初始化对象的值注意:1、与java相比,java只有一个构造器。而python  __new__  方法与 __init__ 方法 组合,才能称为一个对应类似于java中的构造器 2、先执行__new__ ,创建对象,并分配内存.再执行 __init__,初始化对象的值。3、任何类都继承于object 类。我们一般不重写__new__ 方法。 我们不重写,就默认调用父类 的 __new__ 方法。4、__new__ 方法 ,一定要return 一个对象。 如果自己重写__new__ 方法,但是没有return出一个对象。连对象都没创建成功,后面是不会进行初始化对象的。例子1:class Person(object):     def __init__(self,name,id,sex):         self.name = name         self.id = id         self.sex = sex         print("初始化对象的值")       def __new__(cls, *args, **kwargs):         print("开始创建对象,并分配内存")   if __name__ == '__main__':     p = Person("张三",12,"男") 运行结果,只执行了__new__ 方法,并没有执行 __init__方法。为啥呢? 因为new函数,没有返回一个 对象。正确的用法class Person(object):     def __init__(self,name,id,sex):         self.name = name         self.id = id         self.sex = sex         print("初始化对象的值")       def __new__(cls, *args, **kwargs):         print("开始创建对象,并分配内存")         self = super().__new__(cls)         return self   if __name__ == '__main__':     p = Person("张三",12,"男")打印结果:开始创建对象,并分配内存初始化对象的值
  • [技术干货] 基于Python实现绘制一个足球【转】
    如果想优雅地绘制一个足球,那首先需要绘制正二十面体 https://bbs.huaweicloud.com/forum/thread-0275112930670884059-1-1.html import numpy as np from itertools import product G = (np.sqrt(5)-1)/2 def getVertex():     pt2 =  [(a,b) for a,b in product([1,-1], [G, -G])]     pts =  [(a,b,0) for a,b in pt2]     pts += [(0,a,b) for a,b in pt2]     pts += [(b,0,a) for a,b in pt2]     return np.array(pts)  def getDisMat(pts):     N = len(pts)     dMat = np.ones([N,N])*np.inf     for i in range(N):         for j in range(i):             dMat[i,j] = np.linalg.norm([pts[i]-pts[j]])     return dMat  pts = getVertex() dMat = getDisMat(pts) # 由于存在舍入误差,所以得到的边的数值可能不唯一 ix, jx = np.where((dMat-np.min(dMat))<0.01) # 获取正二十面体的边 edges = [pts[[i,j]] for i,j in zip(ix, jx)] def isFace(e1, e2, e3):     pts = np.vstack([e1, e2, e3])     pts = np.unique(pts, axis=0)     return len(pts)==3  from itertools import combinations # 获取正二十面体的面 faces = [es for es in combinations(edges, 3)      if isFace(*es)] 为了克服plot_trisurf在xy坐标系中的bug,需要对足球做一点旋转,所以下面要写入旋转矩阵。 # 将角度转弧度后再求余弦 cos = lambda th : np.cos(np.deg2rad(th)) sin = lambda th : np.sin(np.deg2rad(th))  # 即 Rx(th) => Matrix Rx = lambda th : np.array([     [1, 0,       0],     [0, cos(th), -sin(th)],     [0, sin(th), cos(th)]]) Ry = lambda th : np.array([     [cos(th),  0, sin(th)],     [0      ,  1, 0],     [-sin(th), 0, cos(th)] ]) Rz = lambda th : np.array([     [cos(th) , sin(th), 0],     [-sin(th), cos(th), 0],     [0       , 0,       1]]) 先画六边形足球其实就是正二十面体削掉顶点,正二十面体有20个面和12个顶点,每个面都是三角形。削掉顶点对于三角形而言就是削掉三个角,如果恰好选择在1/3的位置削角,则三角形就变成正六边形;而每个顶点处刚好有5条棱,顶点削去之后就变成了正五边形。而正好足球的六边形和五边形有着不同的颜色,所以可以分步绘制,先来搞定六边形。由于此前已经得到了正二十面体的所有面,同时还有这个面对应的所有边,故而只需在每一条边的1/3 和2/3处截断,就可以得到足球的正六边形。 def getHexEdges(face):     pts = []     for st,ed in face:         pts.append((2*st+ed)/3)         pts.append((st+2*ed)/3)     return np.vstack(pts)  ax = plt.subplot(projection='3d') for f in faces:     pt = getHexEdges(f)     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="white") 再画五边形接下来要做的是,将五边形的窟窿补上,正如一开始说的,这个五边形可以理解为削去顶点而得到的,所以第一件事,就是要找到一个顶点周围的所有边。具体方法就是,对每一个顶点遍历所有边,如果某条边中存在这个顶点,那么就把这个边纳入到这个顶点的连接边。 def getPtEdges(pts, edges):     N = len(pts)     pEdge = [[] for pt in pts]     for i,e in product(range(N),edges):         if (pts[i] == e[0]).all():              pt = (2*pts[i]+e[1])/3         elif (pts[i] == e[1]).all():              pt = (2*pts[i]+e[0])/3         else:             continue         pEdge[i].append(pt)     return np.array(pEdge)  pEdge = getPtEdges(pts, edges) 接下来,就可以绘制足球了 ax = plt.subplot(projection='3d') for f in faces:     pt = getHexEdges(f)     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="white")  for pt in pEdge:     pt = Rx(1)@Ry(1)@pt.T     ax.plot_trisurf(*pt, color="black")  plt.show()