OpenCV入门11——图像的分割与修复

news2024/11/29 6:27:14

文章目录

  • 图像分割的基本概念
  • 实战-分水岭法(一)
  • 实战-分水岭法(二)
  • GrabCut基本原理
  • 实战-GrabCut主体程序的实现
  • 实战-GrabCut鼠标事件的处理
  • 实战-调用GrabCut实现图像分割
  • meanshift图像分割
  • 视频前后景分离
  • 其它对视频前后影分离的方法
  • 图像修复

图像分割是计算机视觉中的一个重要领域,通过它我们可以做物体的统计,背景的变换等许多操作,而图像的修复可以说是它的逆运算

图像分割的基本概念

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实战-分水岭法(一)

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
未知区域就是背景-前景
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)

cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述
把硬币膨胀,背景缩小,保证缩小后的背景里没有硬币,并且开运算可以去除背景的噪声

# -*- coding: utf-8 -*-
import cv2
import numpy as np

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)

cv2.imshow('bg', bg)
cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

实战-分水岭法(二)

在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)

# 获取前景物体
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5);
plt.imshow(dist, cmap='gray')
plt.show()
exit()

cv2.imshow('bg', bg)
cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)

# 获取前景物体
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5);

ret, fg = cv2.threshold(dist, 0.7 * dist.max(), 255, cv2.THRESH_BINARY)

# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()

cv2.imshow('fg', fg)
cv2.imshow('bg', bg)
cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)

# 获取前景物体
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5);

ret, fg = cv2.threshold(dist, 0.7 * dist.max(), 255, cv2.THRESH_BINARY)

# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()

# 获取未知区域
fg = np.uint8(fg)
unknown = cv2.subtract(bg, fg)


cv2.imshow('unknown', unknown)
cv2.imshow('fg', fg)
cv2.imshow('bg', bg)
cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述
计算前景色的连通域

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

#获取背景 
# 1. 通过二值法得到黑白图片
# 2. 通过形态学获取背景

img = cv2.imread('./water_coins.jpeg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 二值化
ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# 开运算
kernel = np.ones((3, 3), np.int8)
open1 = cv2.morphologyEx(thresh, cv2.MORPH_OPEN, kernel, iterations=2)

# 膨胀
bg = cv2.dilate(open1, kernel, iterations=1)

# 获取前景物体
dist = cv2.distanceTransform(open1, cv2.DIST_L2, 5);

ret, fg = cv2.threshold(dist, 0.7 * dist.max(), 255, cv2.THRESH_BINARY)

# plt.imshow(dist, cmap='gray')
# plt.show()
# exit()

# 获取未知区域
fg = np.uint8(fg)
unknown = cv2.subtract(bg, fg)

# 创建连通域
ret, marker = cv2.connectedComponents(fg)
print(marker)
marker = marker + 1
print(marker)
marker[unknown == 255] = 0

# 进行图像分割
result = cv2.watershed(img, marker)
img[result == -1] = [0, 0, 255]


cv2.imshow('img', img)
cv2.imshow('unknown', unknown)
cv2.imshow('fg', fg)
cv2.imshow('bg', bg)
cv2.imshow('thresh', thresh)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
详细操作见官方文档
在这里插入图片描述
在这里插入图片描述

GrabCut基本原理

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

实战-GrabCut主体程序的实现

# -*- coding: utf-8 -*-
import cv2
import numpy as np

class App:
    def onmouse(self, event, x, y, flags, param):
        print("onmouse")
    def run(self):
        print("run...")

        cv2.namedWindow('input', cv2.WINDOW_NORMAL)
        cv2.setMouseCallback('input', self.onmouse)

        img = cv2.imread('./lena.png')
        cv2.imshow('input', img)
        if cv2.waitKey(0) & 0xff == 27:
            cv2.destroyAllWindows()
        
App().run()

在这里插入图片描述

实战-GrabCut鼠标事件的处理

# -*- coding: utf-8 -*-
import cv2
import numpy as np

class App:
    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            print("EVENT_LBUTTONUP")
        elif event == cv2.EVENT_MOUSEMOVE:
            print("EVENT_MOUSEMOVE")
            
    def run(self):
        print("run...")

        cv2.namedWindow('input', cv2.WINDOW_NORMAL)
        cv2.setMouseCallback('input', self.onmouse)

        img = cv2.imread('./lena.png')
        cv2.imshow('input', img)
        if cv2.waitKey(0) & 0xff == 27:
            cv2.destroyAllWindows()
        
App().run()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

class App:
    startX = 0
    startY = 0

    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            self.startX = x
            self.startY = y
            # print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (0, 255, 0), 2)
            # print("EVENT_LBUTTONUP")
        elif event == cv2.EVENT_MOUSEMOVE:
            print("EVENT_MOUSEMOVE")

    def run(self):
        print("run...")

        cv2.namedWindow('input', cv2.WINDOW_NORMAL)
        cv2.setMouseCallback('input', self.onmouse)
        # 隐式的定义成员变量
        self.img = cv2.imread('./lena.png')
        while True:
            cv2.imshow('input', self.img)
            if cv2.waitKey(100) & 0xff == 27:
                cv2.destroyAllWindows()
                break
        
App().run()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

class App:
    startX = 0
    startY = 0
    flag_rect = False

    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            self.flag_rect = True
            self.startX = x
            self.startY = y
            # print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (0, 255, 0), 3)
            self.flag_rect = False
            # print("EVENT_LBUTTONUP")
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.flag_rect == True:
                #鼠标每次移动的时候再拷贝一份img2到img用于显示(img会一直刷新,所以之前鼠标移动画的不会影响后面)
                self.img = self.img2.copy()
                cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (255, 255, 0), 3)
            # print("EVENT_MOUSEMOVE")

    def run(self):
        print("run...")

        cv2.namedWindow('input', cv2.WINDOW_NORMAL)
        cv2.setMouseCallback('input', self.onmouse)
        # 隐式的定义成员变量
        self.img = cv2.imread('./lena.png')
        self.img2 = self.img.copy()

        while True:
            cv2.imshow('input', self.img)
            if cv2.waitKey(100) & 0xff == 27:
                cv2.destroyAllWindows()
                break
        
App().run()

在这里插入图片描述

实战-调用GrabCut实现图像分割

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

class App:
    startX = 0
    startY = 0
    flag_rect = False
    rect = (0, 0, 0, 0)

    def onmouse(self, event, x, y, flags, param):
        # print("onmouse")
        if event == cv2.EVENT_LBUTTONDOWN:
            self.flag_rect = True
            self.startX = x
            self.startY = y
            # print("LBUTTONDOWN")
        elif event == cv2.EVENT_LBUTTONUP:
            cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (0, 255, 0), 3)
            self.flag_rect = False
            self.rect = (min(self.startX, x), min(self.startY, y), 
                      abs(self.startX - x), abs(self.startY - y))
            # print("EVENT_LBUTTONUP")
        elif event == cv2.EVENT_MOUSEMOVE:
            if self.flag_rect == True:
                #鼠标每次移动的时候再拷贝一份img2到img用于显示(img会一直刷新,所以之前鼠标移动画的不会影响后面)
                self.img = self.img2.copy()
                cv2.rectangle(self.img, (self.startX, self.startY), (x, y), (255, 255, 0), 3)
            # print("EVENT_MOUSEMOVE")

    def run(self):
        print("run...")

        cv2.namedWindow('input', cv2.WINDOW_NORMAL)
        cv2.setMouseCallback('input', self.onmouse)
        # 隐式的定义成员变量
        self.img = cv2.imread('./lena.png')
        self.img2 = self.img.copy()
        self.mask = np.zeros(self.img.shape[:2], dtype=np.uint8)
        self.output = np.zeros(self.img.shape, np.uint8)

        while True:
            cv2.imshow('input', self.img)
            cv2.imshow('output', self.output)
            k = cv2.waitKey(100)
            if k & 0xff == 27:
                cv2.destroyAllWindows()
                break
            if k & 0xff == ord('g'):
                bgdmodel = np.zeros((1, 65), np.float64)
                fgdmodel = np.zeros((1, 65), np.float64)
                cv2.grabCut(self.img2, self.mask, self.rect, bgdmodel, fgdmodel, 1, cv2.GC_INIT_WITH_RECT)
            mask2 = np.where((self.mask==1) | (self.mask == 3), 255, 0).astype('uint8')
            self.output = cv2.bitwise_and(self.img2, self.img2, mask=mask2)
                
App().run()

在这里插入图片描述
在这里插入图片描述

meanshift图像分割

基于色彩进行图像分割
在这里插入图片描述
在这里插入图片描述
sp越大模糊程度越大,sp越小模糊程度越小

sr越大,连成一片区域的可能性越大
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

img = cv2.imread('flower.png')
mean_img = cv2.pyrMeanShiftFiltering(img, 20, 30)

cv2.imshow('img', img)
cv2.imshow('mean_img', mean_img)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

# cv2.namedWindow('img', cv2.WINDOW_NORMAL)
# cv2.namedWindow('mean_img', cv2.WINDOW_NORMAL)
img = cv2.imread('flower.png')
# img = cv2.imread('E:/pic/picc/IMG_20230610_192709.jpg')
mean_img = cv2.pyrMeanShiftFiltering(img, 20, 30)

imgCanny = cv2.Canny(mean_img, 150, 200)

cv2.imshow('img', img)
cv2.imshow('mean_img', mean_img)
cv2.imshow('imgCanny', imgCanny)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

# cv2.namedWindow('img', cv2.WINDOW_NORMAL)
# cv2.namedWindow('mean_img', cv2.WINDOW_NORMAL)
# img = cv2.imread('flower.png')
img = cv2.imread('key.png')
# img = cv2.imread('E:/pic/picc/IMG_20230610_192709.jpg')
mean_img = cv2.pyrMeanShiftFiltering(img, 20, 30)

imgCanny = cv2.Canny(mean_img, 150, 200)

contours, hierarchy = cv2.findContours(imgCanny, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)

cv2.drawContours(img, contours, -1, (0, 255, 0), 2)

cv2.imshow('img', img)
cv2.imshow('mean_img', mean_img)
cv2.imshow('imgCanny', imgCanny)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

视频前后景分离

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

cap = cv2.VideoCapture('./MyVideo.wmv')
mog = cv2.bgsegm.createBackgroundSubtractorMOG()

while True:
    ret, frame = cap.read()
    fgmask = mog.apply(frame)

    cv2.imshow('img', fgmask)
    k = cv2.waitKey(40)
    if k & 0xff == 27:
        break
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

其它对视频前后影分离的方法

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

cap = cv2.VideoCapture('./MyVideo.wmv')
# mog = cv2.bgsegm.createBackgroundSubtractorMOG()
# 优点:可以计算出阴影部分
# 缺点:会产生很多噪点
mog = cv2.createBackgroundSubtractorMOG2()

while True:
    ret, frame = cap.read()
    fgmask = mog.apply(frame)

    cv2.imshow('img', fgmask)
    k = cv2.waitKey(40)
    if k & 0xff == 27:
        break
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述
在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

cv2.namedWindow('img', cv2.WINDOW_NORMAL)
cap = cv2.VideoCapture('./MyVideo.wmv')
# mog = cv2.bgsegm.createBackgroundSubtractorMOG()
# 优点:可以计算出阴影部分
# 缺点:会产生很多噪点
# mog = cv2.createBackgroundSubtractorMOG2()

# 优点:可以算出阴影部分,同时减少了噪点
# 缺点:如果采用默认值,则在开始一段时间内没有任何信息显示
# 解决办法:调整初始参考帧数量
mog = cv2.bgsegm.createBackgroundSubtractorGMG()

while True:
    ret, frame = cap.read()
    fgmask = mog.apply(frame)

    cv2.imshow('img', fgmask)
    k = cv2.waitKey(40)
    if k & 0xff == 27:
        break
cap.release()
cv2.destroyAllWindows()

在这里插入图片描述

图像修复

在这里插入图片描述
在这里插入图片描述
生成掩码

# -*- coding: utf-8 -*-
import cv2          
import numpy as np
 
start_point=(0,0) #鼠标开始坐标
lb_down = False #鼠标左键按下的标志,bool型
 
def mouse_event(event,x,y,flags,param):
    global start_point,end_point,lb_down 
    #如果全局变量是int或者str,那么如果想要在函数中对函数变量进行修改,则需要
    #先在函数内,声明其为global,再进行修改,如果是list或者dict则可以直接修改
    
    #左键按下,更新鼠标坐标,启动按下标志
    if event == cv2.EVENT_LBUTTONDOWN:  
        start_point = (x,y)
        lb_down = True
    
    #鼠标移动,绘制线
    elif event == cv2.EVENT_MOUSEMOVE and lb_down: 
        cv2.line(img,start_point,(x,y),(0,0,255),thickness=8)
        cv2.line(mask,start_point,(x,y),(255,255,255),thickness=8)
        #只要鼠标移动,就更新鼠标的坐标  
        start_point = (x,y)      

    #左键释放
    elif event == cv2.EVENT_LBUTTONUP: 
        #鼠标点击后直接释放鼠标的时候也会绘制一个点
        cv2.line(img,start_point,(x,y),(255,255,255),thickness=5)  
        cv2.line(mask,start_point,(x,y),(255,255,255),thickness=5)
        lb_down = False
 
 
cv2.namedWindow('image')   #新建窗口,用来进行鼠标操作       
img = cv2.imread('./inpaint.png')       
mask = np.zeros(img.shape, np.uint8)  #创建一个黑色mask图像
 
cv2.setMouseCallback('image',mouse_event)  #设置鼠标回调
 
while True:
    cv2.imshow('image',img)
    cv2.imshow('mask',mask)
    if cv2.waitKey(1)==ord('q'): #waitKey参数不能写0,写0就需要键盘输入才会继续
        break
cv2.imwrite("./mask.png", mask)
cv2.destroyAllWindows()

在这里插入图片描述

# -*- coding: utf-8 -*-
import cv2
import numpy as np

img = cv2.imread('inpaint.png')
mask = cv2.imread('mask.png', 0)

dst = cv2.inpaint(img, mask, 5, cv2.INPAINT_TELEA)

cv2.imshow('dst', dst)
cv2.imshow('img', img)
if cv2.waitKey(0) & 0xff == 27:
    cv2.destroyAllWindows()

在这里插入图片描述

效果很差。。。
之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1256399.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

window环境搭建StarRocksFE节点

StarRocks部署–源码编译 前言 ​ 注意:本文借用了一些其他文章的一些截图,同时自己做了具体的编译步骤,添加了一些新的内容 ​ 目标: 编译StarRocks2.5.13版本FE节点代码,在本地window环境运行,可以访问到8030界面…

频剪辑软件Corel VideoStudio 会声会影2024最新7大新全新功能解析

我很喜欢视频剪辑软件Corel VideoStudio 会声会影2024,因为它使用起来很有趣。它很容易使用,但仍然给你很多功能和力量。视频剪辑软件Corel VideoStudio 会声会影2023让我与世界分享我的想法!“这个产品的功能非常多,我几乎没有触…

【数据中台】开源项目(2)-Wormhole流式处理平台

Wormhole 是一个一站式流式处理云平台解决方案(SPaaS - Stream Processing as a Service)。 Wormhole 面向大数据流式处理项目的开发管理运维人员,致力于提供统一抽象的概念体系,直观可视化的操作界面,简单流畅的配置管…

《已解决: ImportError: Keras requires TensorFlow 2.2 or higher 问题》

🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页: 🐅🐾猫头虎的博客🎐《面试题大全专栏》 🦕 文章图文并茂&#x1f996…

vscode 使用git提交前端代码

1、项目初始化git 如果是从其他地方拉的代码,把.git文件删除,再重新初始化。 2、提交代码 2.1、提交本地库 2.2、提交远程仓库 2.2.1、创建远程仓库 2.2.2、提交远程仓库–master分支 在本地添加远程仓库,设置别名为origin git remote…

首届教师案例教学竞赛一等奖作品上线至和鲸社区,快来学习!

细心的朋友可能已经发现,近期和鲸社区的频道页上线了一个新专区——“优秀参赛作品专区”。 图.和鲸社区频道页 迄今为止,和鲸参与/支持了 500 多场专业数据科学竞赛,包括面向气象、金融、医学、海洋等不同领域的,面向从业者、科学…

为你的项目加上微信登录(个人开发)

当我们开发个人项目的时候,为了用户登录的便捷性,经常会给我们的项目加上一些除了注册之外的方式,其中最常见的就是微信登录,但作为个人开发者,是无法使用微信的授权登录的,但是通过微信公众号可以获得同样…

【nginx】 实现限流

这里写自定义目录标题 前言正文nginx实现限流并发限制限制单IP并发数量限制单主机服务并发数量 速率限制限流效果 注意疑问参考链接 小结 前言 好久不见,还算为时不晚。最近一个月经历了工作的调整,技术栈从Java转向了Go和Python, 工作显得更忙了些&…

JavaScript基础—for语句、循环嵌套、数组、冒泡排序、综合案例—根据数据生成柱形图

版本说明 当前版本号[20231126]。 版本修改说明20231126初版 目录 文章目录 版本说明目录JavaScript 基础第三天笔记for 语句for语句的基本使用循环嵌套倒三角九九乘法表 数组数组是什么?数组的基本使用定义数组和数组单元访问数组和数组索引数据单元值类型数组长…

测试工程师必学看系列之Jmeter_性能测试:性能测试的流程和术语

性能测试的流程 一、准备工作 1、系统基础功能验证 一般情况下,只有在系统基础功能测试验证完成、系统趋于稳定的情况下,才会进行性能测试,否则性能测试是无意义的。2、测试团队组建 根据该项目的具体情况,组建一个几人的性能测试…

Linux面试题(三)

目录 34、du 和 df 的定义,以及区别? 35、awk 详解。 36、当你需要给命令绑定一个宏或者按键的时候,应该怎么做呢? 37、如果一个 linux 新手想要知道当前系统支持的所有命令的列表,他需要怎么做? 38、…

23年几个能打的UE4游戏技术选型

近期发现很多的精力放在游戏的整体技术选型以及产生的结果上面,所以回顾下几个游戏的选型和结果; 这里一个是自己玩游戏的画面流畅度的直接感受,以及一直非常喜爱的评测“数毛社”,digital foundry; 23年目前来看&…

【NeRF】3、MobileR2L | 移动端实时的神经光场(CVPR2023)

论文:Real-Time Neural Light Field on Mobile Devices 代码:https://github.com/snap-research/MobileR2L 出处:CVPR2023 贡献: 设计了一套移动端实时的 R2L 网络结构 MobileR2L,在 iphone13 上渲染一张 1008x756…

前端学习--React(4)路由

一、认识ReactRouter 一个路径path对应一个组件component,当我们在浏览器中访问一个path,对应的组件会在页面进行渲染 创建路由项目 // 创建项目 npx create router-demo// 安装路由依赖包 npm i react-router-dom// 启动项目 npm run start 简单的路…

【JavaEE】多线程 (2) --线程安全

目录 1. 观察线程不安全 2. 线程安全的概念 3. 线程不安全的原因 4. 解决之前的线程不安全问题 5. synchronized 关键字 - 监视器锁 monitor lock 5.1 synchronized 的特性 5.2 synchronized 使⽤⽰例 1. 观察线程不安全 package thread; public class ThreadDemo19 {p…

LeetCode中链表类题目十条血泪经验总结-全程干货

文章目录 前言干货经验汇总第一梯队第二梯队 力扣代表性链表题目推荐 前言 链表是以节点(node)存储的链式存储结构,一个node包含一个data域(存放数据)和一个next域(存放下一个node的指针)&…

Co-DETR:DETRs与协同混合分配训练论文学习笔记

论文地址:https://arxiv.org/pdf/2211.12860.pdf 代码地址: GitHub - Sense-X/Co-DETR: [ICCV 2023] DETRs with Collaborative Hybrid Assignments Training 摘要 作者提出了一种新的协同混合任务训练方案,即Co-DETR,以从多种标…

Web框架与Django简介

Web框架与Django简介 一、Web应用的组成 我们为了开发一款Web软件首先要了解什么才是Web应用软件呢? 对于传统的应用软件来说,基本都是部署单机使用,而Web应用软件就不一样,Web应用软件是基于B/S架构的,B和S都在不同…

Vue常见的实现tab切换的两种方法

目录 方法一&#xff1a;事件绑定属性绑定 效果图 完整代码 方法二&#xff1a;属性绑定 动态组件 component标签 效果图 完整代码 方法一&#xff1a;事件绑定属性绑定 效果图 完整代码 <!DOCTYPE html> <html lang"en"> <head><meta c…

Qt 样式表

QLabel&#xff0c;应用于Widget&#xff1a; .QLabel {background-color:pink; }.QLabel[warnlevel_1] {border:5px solid yellow; }.QLabel[warnlevel_2] {border:5px solid red; } QWidget{background-color:rgb(54,54,54); }QLineEdit{border: 1px solid #ABCDA0; /…