基于深度学习的显著性检测用于遥感影像地物提取(U-2-NET)

article/2025/10/12 7:27:28

GitHub地址链接:https://github.com/NathanUA/U-2-Net
这个显著性检测很好用,强烈推荐,建议二分类的任务都来试试,尤其对边缘细节要求比较高的任务。
下面的效果要不是第一张图预测有瑕疵,我都以为预测代码是把标签复制了一下(+_+)
这里的精度我就不评价了,肉眼看就已经能说明问题了
原图
原图
标签
标签
预测结果:
结果
1.数据准备
和传统的语义分割数据集存放目录是一致的,Image和Mask里面是名字一一对应(名字相同,后缀可以不同,代码里可以改后缀识别,jpg png这些都行)的图像—标签对
数据
2.训练
data_loader.py,在222行左右,需要加copy()

# data loader
from __future__ import print_function, division
import glob
import torch
from skimage import io, transform, color
import numpy as np
import random
import math
import matplotlib.pyplot as plt
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
from PIL import Image#==========================dataset load==========================
class RescaleT(object):def __init__(self,output_size):assert isinstance(output_size,(int,tuple))self.output_size = output_sizedef __call__(self,sample):imidx, image, label = sample['imidx'], sample['image'],sample['label']h, w = image.shape[:2]if isinstance(self.output_size,int):if h > w:new_h, new_w = self.output_size*h/w,self.output_sizeelse:new_h, new_w = self.output_size,self.output_size*w/helse:new_h, new_w = self.output_sizenew_h, new_w = int(new_h), int(new_w)# #resize the image to new_h x new_w and convert image from range [0,255] to [0,1]# img = transform.resize(image,(new_h,new_w),mode='constant')# lbl = transform.resize(label,(new_h,new_w),mode='constant', order=0, preserve_range=True)img = transform.resize(image,(self.output_size,self.output_size),mode='constant')lbl = transform.resize(label,(self.output_size,self.output_size),mode='constant', order=0, preserve_range=True)return {'imidx':imidx, 'image':img,'label':lbl}class Rescale(object):def __init__(self,output_size):assert isinstance(output_size,(int,tuple))self.output_size = output_sizedef __call__(self,sample):imidx, image, label = sample['imidx'], sample['image'],sample['label']if random.random() >= 0.5:image = image[::-1]label = label[::-1]h, w = image.shape[:2]if isinstance(self.output_size,int):if h > w:new_h, new_w = self.output_size*h/w,self.output_sizeelse:new_h, new_w = self.output_size,self.output_size*w/helse:new_h, new_w = self.output_sizenew_h, new_w = int(new_h), int(new_w)# #resize the image to new_h x new_w and convert image from range [0,255] to [0,1]img = transform.resize(image,(new_h,new_w),mode='constant')lbl = transform.resize(label,(new_h,new_w),mode='constant', order=0, preserve_range=True)return {'imidx':imidx, 'image':img,'label':lbl}class RandomCrop(object):def __init__(self,output_size):assert isinstance(output_size, (int, tuple))if isinstance(output_size, int):self.output_size = (output_size, output_size)else:assert len(output_size) == 2self.output_size = output_sizedef __call__(self,sample):imidx, image, label = sample['imidx'], sample['image'], sample['label']if random.random() >= 0.5:image = image[::-1]label = label[::-1]h, w = image.shape[:2]new_h, new_w = self.output_sizetop = np.random.randint(0, h - new_h)left = np.random.randint(0, w - new_w)image = image[top: top + new_h, left: left + new_w]label = label[top: top + new_h, left: left + new_w]return {'imidx':imidx,'image':image, 'label':label}class ToTensor(object):"""Convert ndarrays in sample to Tensors."""def __call__(self, sample):imidx, image, label = sample['imidx'], sample['image'], sample['label']tmpImg = np.zeros((image.shape[0],image.shape[1],3))tmpLbl = np.zeros(label.shape)image = image/np.max(image)if(np.max(label)<1e-6):label = labelelse:label = label/np.max(label)if image.shape[2]==1:tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,1] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,2] = (image[:,:,0]-0.485)/0.229else:tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,1] = (image[:,:,1]-0.456)/0.224tmpImg[:,:,2] = (image[:,:,2]-0.406)/0.225tmpLbl[:,:,0] = label[:,:,0]# change the r,g,b to b,r,g from [0,255] to [0,1]#transforms.Normalize(mean = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225))tmpImg = tmpImg.transpose((2, 0, 1))tmpLbl = label.transpose((2, 0, 1))return {'imidx':torch.from_numpy(imidx), 'image': torch.from_numpy(tmpImg), 'label': torch.from_numpy(tmpLbl)}class ToTensorLab(object):"""Convert ndarrays in sample to Tensors."""def __init__(self,flag=0):self.flag = flagdef __call__(self, sample):imidx, image, label =sample['imidx'], sample['image'], sample['label']tmpLbl = np.zeros(label.shape)if(np.max(label)<1e-6):label = labelelse:label = label/np.max(label)# change the color spaceif self.flag == 2: # with rgb and Lab colorstmpImg = np.zeros((image.shape[0],image.shape[1],6))tmpImgt = np.zeros((image.shape[0],image.shape[1],3))if image.shape[2]==1:tmpImgt[:,:,0] = image[:,:,0]tmpImgt[:,:,1] = image[:,:,0]tmpImgt[:,:,2] = image[:,:,0]else:tmpImgt = imagetmpImgtl = color.rgb2lab(tmpImgt)# nomalize image to range [0,1]tmpImg[:,:,0] = (tmpImgt[:,:,0]-np.min(tmpImgt[:,:,0]))/(np.max(tmpImgt[:,:,0])-np.min(tmpImgt[:,:,0]))tmpImg[:,:,1] = (tmpImgt[:,:,1]-np.min(tmpImgt[:,:,1]))/(np.max(tmpImgt[:,:,1])-np.min(tmpImgt[:,:,1]))tmpImg[:,:,2] = (tmpImgt[:,:,2]-np.min(tmpImgt[:,:,2]))/(np.max(tmpImgt[:,:,2])-np.min(tmpImgt[:,:,2]))tmpImg[:,:,3] = (tmpImgtl[:,:,0]-np.min(tmpImgtl[:,:,0]))/(np.max(tmpImgtl[:,:,0])-np.min(tmpImgtl[:,:,0]))tmpImg[:,:,4] = (tmpImgtl[:,:,1]-np.min(tmpImgtl[:,:,1]))/(np.max(tmpImgtl[:,:,1])-np.min(tmpImgtl[:,:,1]))tmpImg[:,:,5] = (tmpImgtl[:,:,2]-np.min(tmpImgtl[:,:,2]))/(np.max(tmpImgtl[:,:,2])-np.min(tmpImgtl[:,:,2]))# tmpImg = tmpImg/(np.max(tmpImg)-np.min(tmpImg))tmpImg[:,:,0] = (tmpImg[:,:,0]-np.mean(tmpImg[:,:,0]))/np.std(tmpImg[:,:,0])tmpImg[:,:,1] = (tmpImg[:,:,1]-np.mean(tmpImg[:,:,1]))/np.std(tmpImg[:,:,1])tmpImg[:,:,2] = (tmpImg[:,:,2]-np.mean(tmpImg[:,:,2]))/np.std(tmpImg[:,:,2])tmpImg[:,:,3] = (tmpImg[:,:,3]-np.mean(tmpImg[:,:,3]))/np.std(tmpImg[:,:,3])tmpImg[:,:,4] = (tmpImg[:,:,4]-np.mean(tmpImg[:,:,4]))/np.std(tmpImg[:,:,4])tmpImg[:,:,5] = (tmpImg[:,:,5]-np.mean(tmpImg[:,:,5]))/np.std(tmpImg[:,:,5])elif self.flag == 1: #with Lab colortmpImg = np.zeros((image.shape[0],image.shape[1],3))if image.shape[2]==1:tmpImg[:,:,0] = image[:,:,0]tmpImg[:,:,1] = image[:,:,0]tmpImg[:,:,2] = image[:,:,0]else:tmpImg = imagetmpImg = color.rgb2lab(tmpImg)# tmpImg = tmpImg/(np.max(tmpImg)-np.min(tmpImg))tmpImg[:,:,0] = (tmpImg[:,:,0]-np.min(tmpImg[:,:,0]))/(np.max(tmpImg[:,:,0])-np.min(tmpImg[:,:,0]))tmpImg[:,:,1] = (tmpImg[:,:,1]-np.min(tmpImg[:,:,1]))/(np.max(tmpImg[:,:,1])-np.min(tmpImg[:,:,1]))tmpImg[:,:,2] = (tmpImg[:,:,2]-np.min(tmpImg[:,:,2]))/(np.max(tmpImg[:,:,2])-np.min(tmpImg[:,:,2]))tmpImg[:,:,0] = (tmpImg[:,:,0]-np.mean(tmpImg[:,:,0]))/np.std(tmpImg[:,:,0])tmpImg[:,:,1] = (tmpImg[:,:,1]-np.mean(tmpImg[:,:,1]))/np.std(tmpImg[:,:,1])tmpImg[:,:,2] = (tmpImg[:,:,2]-np.mean(tmpImg[:,:,2]))/np.std(tmpImg[:,:,2])else: # with rgb colortmpImg = np.zeros((image.shape[0],image.shape[1],3))image = image/np.max(image)if image.shape[2]==1:tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,1] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,2] = (image[:,:,0]-0.485)/0.229else:tmpImg[:,:,0] = (image[:,:,0]-0.485)/0.229tmpImg[:,:,1] = (image[:,:,1]-0.456)/0.224tmpImg[:,:,2] = (image[:,:,2]-0.406)/0.225tmpLbl[:,:,0] = label[:,:,0]# change the r,g,b to b,r,g from [0,255] to [0,1]#transforms.Normalize(mean = (0.485, 0.456, 0.406), std = (0.229, 0.224, 0.225))tmpImg = tmpImg.transpose((2, 0, 1))tmpLbl = label.transpose((2, 0, 1))return {'imidx':torch.from_numpy(imidx.copy()), 'image': torch.from_numpy(tmpImg.copy()), 'label': torch.from_numpy(tmpLbl.copy())} #需要加.copy()class SalObjDataset(Dataset):def __init__(self,img_name_list,lbl_name_list,transform=None):# self.root_dir = root_dir# self.image_name_list = glob.glob(image_dir+'*.png')# self.label_name_list = glob.glob(label_dir+'*.png')self.image_name_list = img_name_listself.label_name_list = lbl_name_listself.transform = transformdef __len__(self):return len(self.image_name_list)def __getitem__(self,idx):# image = Image.open(self.image_name_list[idx])#io.imread(self.image_name_list[idx])# label = Image.open(self.label_name_list[idx])#io.imread(self.label_name_list[idx])image = io.imread(self.image_name_list[idx])imname = self.image_name_list[idx]imidx = np.array([idx])if(0==len(self.label_name_list)):label_3 = np.zeros(image.shape)else:label_3 = io.imread(self.label_name_list[idx])label = np.zeros(label_3.shape[0:2])if(3==len(label_3.shape)):label = label_3[:,:,0]elif(2==len(label_3.shape)):label = label_3if(3==len(image.shape) and 2==len(label.shape)):label = label[:,:,np.newaxis]elif(2==len(image.shape) and 2==len(label.shape)):image = image[:,:,np.newaxis]label = label[:,:,np.newaxis]sample = {'imidx':imidx, 'image':image, 'label':label}if self.transform:sample = self.transform(sample)return sample

训练代码基本不用改,主要是路径拼接能找到图像路径就好了
u2net_train.py

import torch
import torchvision
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as Ffrom torch.utils.data import Dataset, DataLoader
from torchvision import transforms, utils
import torch.optim as optim
import torchvision.transforms as standard_transformsimport os
import numpy as np
import globfrom data_loader import Rescale
from data_loader import RescaleT
from data_loader import RandomCrop
from data_loader import ToTensor
from data_loader import ToTensorLab
from data_loader import SalObjDatasetfrom model import U2NET
from model import U2NETP# ------- 1. define loss function --------bce_loss = nn.BCELoss(size_average=True)def muti_bce_loss_fusion(d0, d1, d2, d3, d4, d5, d6, labels_v):loss0 = bce_loss(d0,labels_v)loss1 = bce_loss(d1,labels_v)loss2 = bce_loss(d2,labels_v)loss3 = bce_loss(d3,labels_v)loss4 = bce_loss(d4,labels_v)loss5 = bce_loss(d5,labels_v)loss6 = bce_loss(d6,labels_v)loss = loss0 + loss1 + loss2 + loss3 + loss4 + loss5 + loss6print("l0: %3f, l1: %3f, l2: %3f, l3: %3f, l4: %3f, l5: %3f, l6: %3f\n"%(loss0.item(),loss1.item(),loss2.item(),loss3.item(),loss4.item(),loss5.item(),loss6.item())) #源码里这里有可能报错,如果报了改成和我一样应该就好了return loss0, loss# ------- 2. set the directory of training dataset --------model_name = 'u2net' #'u2netp or u2net'   #有两个模型可以选,选择的标记在下面训练开始前data_dir = os.path.join(os.getcwd(), 'data' + os.sep)
# tra_image_dir = os.path.join('DUTS', 'DUTS-TR', 'DUTS-TR', 'im_aug' + os.sep)
# tra_label_dir = os.path.join('DUTS', 'DUTS-TR', 'DUTS-TR', 'gt_aug' + os.sep)tra_image_dir = os.path.join('RIVER', 'Train', 'Image/')  #训练图片的路径
tra_label_dir = os.path.join('RIVER', 'Train', 'Mask/')image_ext = '.png'  #图像后缀,改成自己的图片格式
label_ext = '.png'model_dir = os.path.join(os.getcwd(), 'saved_models', model_name + os.sep)  #模型存储位置
#训练相关参数
epoch_num = 2000
batch_size_train = 6
batch_size_val = 2
train_num = 0
val_num = 0tra_img_name_list = glob.glob(data_dir + tra_image_dir + '*' + image_ext)tra_lbl_name_list = []
for img_path in tra_img_name_list:img_name = img_path.split(os.sep)[-1]aaa = img_name.split(".")bbb = aaa[0:-1]imidx = bbb[0]for i in range(1,len(bbb)):imidx = imidx + "." + bbb[i]tra_lbl_name_list.append(data_dir + tra_label_dir + imidx + label_ext)print("---")
print("train images: ", len(tra_img_name_list))
print("train labels: ", len(tra_lbl_name_list))
print("---")train_num = len(tra_img_name_list)salobj_dataset = SalObjDataset(img_name_list=tra_img_name_list,lbl_name_list=tra_lbl_name_list,transform=transforms.Compose([RescaleT(320),RandomCrop(288),ToTensorLab(flag=0)]))
salobj_dataloader = DataLoader(salobj_dataset, batch_size=batch_size_train, shuffle=True, num_workers=0)# ------- 3. define model --------
# define the net
#选择模型
if(model_name=='u2net'):net = U2NET(3, 1)
elif(model_name=='u2netp'):net = U2NETP(3,1)if torch.cuda.is_available():net.cuda()# ------- 4. define optimizer --------
print("---define optimizer...")
optimizer = optim.Adam(net.parameters(), lr=0.001, betas=(0.9, 0.999), eps=1e-08, weight_decay=0)# ------- 5. training process --------
print("---start training...")
ite_num = 0
running_loss = 0.0
running_tar_loss = 0.0
ite_num4val = 0
save_frq = 2000 # save the model every 2000 iterations  每迭代两千次存一次模型,这个可以在下面改成每个epoch存,很好改,这里我就不改了for epoch in range(0, epoch_num):net.train()for i, data in enumerate(salobj_dataloader):ite_num = ite_num + 1ite_num4val = ite_num4val + 1inputs, labels = data['image'], data['label']inputs = inputs.type(torch.FloatTensor)labels = labels.type(torch.FloatTensor)# wrap them in Variableif torch.cuda.is_available():inputs_v, labels_v = Variable(inputs.cuda(), requires_grad=False), Variable(labels.cuda(),requires_grad=False)else:inputs_v, labels_v = Variable(inputs, requires_grad=False), Variable(labels, requires_grad=False)# y zero the parameter gradientsoptimizer.zero_grad()# forward + backward + optimized0, d1, d2, d3, d4, d5, d6 = net(inputs_v)loss2, loss = muti_bce_loss_fusion(d0, d1, d2, d3, d4, d5, d6, labels_v)loss.backward()optimizer.step()# # print statisticsrunning_loss += loss.item()running_tar_loss += loss2.item()# del temporary outputs and lossdel d0, d1, d2, d3, d4, d5, d6, loss2, lossprint("[epoch: %3d/%3d, batch: %5d/%5d, ite: %d] train loss: %3f, tar: %3f " % (epoch + 1, epoch_num, (i + 1) * batch_size_train, train_num, ite_num, running_loss / ite_num4val, running_tar_loss / ite_num4val))if ite_num % save_frq == 0:torch.save(net.state_dict(), model_dir + model_name+"_bce_itr_%d_train_%3f_tar_%3f.pth" % (ite_num, running_loss / ite_num4val, running_tar_loss / ite_num4val))running_loss = 0.0running_tar_loss = 0.0net.train()  # resume trainite_num4val = 0

3.预测
u2net_test.py

import os
from skimage import io, transform
import torch
import torchvision
from torch.autograd import Variable
import torch.nn as nn
import torch.nn.functional as F
from torch.utils.data import Dataset, DataLoader
from torchvision import transforms#, utils
# import torch.optim as optimimport numpy as np
from PIL import Image
import globfrom data_loader import RescaleT
from data_loader import ToTensor
from data_loader import ToTensorLab
from data_loader import SalObjDatasetfrom model import U2NET # full size version 173.6 MB
from model import U2NETP # small version u2net 4.7 MB# normalize the predicted SOD probability map
def normPRED(d):ma = torch.max(d)mi = torch.min(d)dn = (d-mi)/(ma-mi)return dndef save_output(image_name,pred,d_dir):predict = predpredict = predict.squeeze()predict_np = predict.cpu().data.numpy()im = Image.fromarray(predict_np*255).convert('RGB')img_name = image_name.split(os.sep)[-1]image = io.imread(image_name)imo = im.resize((image.shape[1],image.shape[0]),resample=Image.BILINEAR)pb_np = np.array(imo)aaa = img_name.split(".")bbb = aaa[0:-1]imidx = bbb[0]for i in range(1,len(bbb)):imidx = imidx + "." + bbb[i]imo.save(d_dir+imidx+'.png')def main():# --------- 1. get image path and name ---------model_name='u2net'#u2netp  #模型名字和训练一致# image_dir = os.path.join(os.getcwd(), 'test_data', 'test_images')image_dir = 'D:/wcs/U-2-Net/data/RIVER/Test/Image/'  #测试图像路径# prediction_dir = os.path.join(os.getcwd(), 'test_data', model_name + '_results' + os.sep)prediction_dir = 'D:/wcs/U-2-Net/data/RIVER/Test/pre/' #保存结果路径model_dir = os.path.join(os.getcwd(), 'saved_models', model_name, model_name + '.pth')img_name_list = glob.glob(image_dir + os.sep + '*')# print(img_name_list)# --------- 2. dataloader ---------#1. dataloadertest_salobj_dataset = SalObjDataset(img_name_list = img_name_list,lbl_name_list = [],transform=transforms.Compose([RescaleT(320),ToTensorLab(flag=0)]))test_salobj_dataloader = DataLoader(test_salobj_dataset,batch_size=1,shuffle=False,num_workers=1)# --------- 3. model define ---------if(model_name=='u2net'):print("...load U2NET---173.6 MB")net = U2NET(3,1)elif(model_name=='u2netp'):print("...load U2NEP---4.7 MB")net = U2NETP(3,1)# net.load_state_dict(torch.load(model_dir))net.load_state_dict(torch.load('./saved_models/u2net/u2net_bce_itr_36000_train_0.091362_tar_0.003286.pth')) #加载自己的模型if torch.cuda.is_available():net.cuda()net.eval()# --------- 4. inference for each image ---------for i_test, data_test in enumerate(test_salobj_dataloader):print("inferencing:",img_name_list[i_test].split(os.sep)[-1])inputs_test = data_test['image']inputs_test = inputs_test.type(torch.FloatTensor)if torch.cuda.is_available():inputs_test = Variable(inputs_test.cuda())else:inputs_test = Variable(inputs_test)d1,d2,d3,d4,d5,d6,d7= net(inputs_test)# normalization# print(d7.shape)pred = d1[:,0,:,:]  #注意这里,这个d1是融合了d2,d3,d4,d5,d6,d7的,如果想了解具体就翻到网络模型去自习看看pred = normPRED(pred)# save results to test_results folderif not os.path.exists(prediction_dir):os.makedirs(prediction_dir, exist_ok=True)save_output(img_name_list[i_test],pred,prediction_dir)del d1,d2,d3,d4,d5,d6,d7if __name__ == "__main__":main()

另外,这个项目在GitHub上展示的人像轮廓提取效果非常好,说明模型关注细节的能力很强,建议需要提取线的相关任务也做做尝试


http://chatgpt.dhexx.cn/article/S5TSkLvv.shtml

相关文章

图像显著性目标检测

一、概述 1、定义 图像显著性检测(Saliency Detection,SD)&#xff0c; 指通过智能算法模拟人的视觉系统特点&#xff0c;预测人类的视觉凝视点和眼动&#xff0c;提取图像中的显著区域(即人类感兴趣的区域)&#xff0c;可以广泛用于目标识别、图像编辑以及图像检索等领域&am…

显著性检测——LC模型

1. 参考文献&#xff1a; Visual Attention Detection in Video Sequences Using Spatiotemporal Cues。 Yun Zhai and Mubarak Shah. Page 4-5 2. 模型实现 2.1 显著性检测公共头文件 #ifndef SALIENTCOMMON_H #define SALIENTCOMMON_H // std lib #include <iostream…

GrabCut算法、物体显著性检测

图割GraphCus算法。利用颜色、纹理等信息对GraphCut进行改进&#xff0c;形成效果更好的GrabCut算法。 对图像的目标物体和背景建立一个K维的全协方差高斯混合模型。 其中&#xff0c;单高斯模型的概率密度函数用公式表示为&#xff1a; 高斯混合模型可表示为n个单高斯模型的概…

显著性检测的评价指标代码

包括MAE、Pre、Rec、F-measure、Auc、CC、Nss MAE&#xff1a; 平均绝对误差MAE&#xff08;mean absolute error&#xff09;&#xff0c;范围[0,∞)&#xff0c;当预测值与真实值完全吻合时等于0&#xff0c;即完美模型&#xff1b;误差越大&#xff0c;该值越大。 Pre、Re…

2023年显著性检测论文及代码汇总

AAAI LeNo: Adversarial Robust Salient Object Detection Networks with Learnable Noise Abstacrt&#xff1a;目前很少有SOD模型对人类视觉注意力难以察觉的对抗性攻击具有鲁棒性。先前的鲁棒显著性ROSA对预分割的超像素进行重组&#xff0c;通过密集连接的条件随机场CRF对…

【显著性检测】Matlab实现Itti显著性检测

目录 理论知识代码步骤读取图像得到金字塔图像提取底层特征计算显著图显著图综合 运行结果展示 理论知识 显著性检测 是指按照人类的视觉注意机制&#xff0c;判断出图像中的显著区域&#xff0c;并为该区域分配较高的显著值&#xff0c;通常认为显著区域更有可能包含目标&…

Opencv之谱残差显著性检测

学习资料参考&#xff1a; 张平.《OpenCV算法精解&#xff1a;基于Python与C》.[Z].北京.电子工业出版社.2017. 前言 在使用谱残差进行显著性检测之前&#xff0c;我们需要理解两个概念&#xff0c;分别是幅度谱和相位谱。 幅度谱和相位谱是将图片进行傅里叶正向变换之后得到的…

显著性检测——GR模型

显著性检测——GR模型 1. Introduction2. Saliency Model2.1 Initial Saliency Map2.2 Saliency Map Refining With Graph Regularization 3. Experiments4. Conclusion参考文献 本人最近在做视觉显著性检测相关的工作&#xff0c;决定把自己的学习经历形成文字&#xff0c;希望…

视频显著性检测----《Flow Guided Recurrent Neural Encoder for Video Salient Object Detection》

本文将重点与大家探讨和分享发表于CVPR2018上的视频显著性检测文章–《Flow Guided Recurrent Neural Encoder for Video Salient Object Detection》&#xff0c;在讨论之前&#xff0c;先带领大家简单回顾一下什么是显著性检测&#xff0c;目前图片显著性检测的常用方法&…

计算机视觉——图像视觉显著性检测

目录 系列文章目录 零、问题描述 一、图像显著性检测 1.定义 2.难点 二、常用评价标准和计算方法 1.综述 2.ROS曲线详述 2.1 混淆矩阵 2.2 ROC曲线简介 2.3 ROC曲线绘制及其判别标准 2.4 ROC曲线补充 三、Fast and Efficient Saliency (FES) 1.算法简介 2.项目导…

显著性检测后处理

将显著性检测图像后处理&#xff0c;绘出一个矩形框&#xff0c;方便使用 先通过边缘检测&#xff0c;然后通过opencv接口实现 结果如下&#xff1a; # --coding:utf # -8-*- import osimport cv2 as cv import numpy as np# canny边缘检测 def canny_demo(image):t 50cann…

基于深度学习的视频显著性检测学习(入门)

一、传统的视频显著性检测 什么是视频显著性检测呢&#xff1f; 我的理解是检测某一段视频的每一帧图片的显著性区域&#xff0c;那这样理解的话就相当于多个图片的显著性检测&#xff0c;所以他是依赖于输入视频帧的对比度、梯度以及纹理来进行相关计算。但既然是视频显著性检…

显著性检测—学习笔记

视觉显著性旨在模仿人类视觉系统选择视觉场景的某个子集的能力。而显著性物体检测&#xff08;SOD&#xff09;则侧重于检测场景中吸引最多注意力的物体&#xff0c;然后逐像素的提取物体的轮廓。SOD的优点在于它在许多计算机视觉任务中均有广泛的应用&#xff0c;包括&#xf…

显著性检测

版权声明&#xff1a;本文为博主原创文章&#xff0c;遵循 CC 4.0 BY-SA 版权协议&#xff0c;转载请附上原文出处链接和本声明。 本文链接&#xff1a; https://blog.csdn.net/qq_32493539/article/details/79530118 转载请附链接&#xff0c;注明出处。 显著性对象检测综述…

在线HTTP接口测试 - HTTP GET/POST模拟请求测试工具

最近发现一个超好用的“在线HTTP接口测试 - HTTP GET/POST模拟请求测试工具”。 链接在此奉上&#xff1a;在线HTTP接口测试 - HTTP GET/POST模拟请求测试工具 很好的一点就是我们只要QQ登录后&#xff0c;就可以记住请求地址&#xff0c;包括请求参数&#xff0c;包括请求co…

https协议的接口测试

用jmeter测试https接口&#xff1a; 和传统的http协议套路不太一样. 注意细节&#xff1a; 1、取样器正常选择http请求&#xff0c;端口号&#xff1a;为443&#xff08;具体根据接口文档我刚开始用的80端口所以错了&#xff09; 2、请求方法&#xff0c;一定一句接口文档&…

接口测试HTTP请求

一、Get请求与Post请求的区别 1.get请求没有请求体&#xff0c;post请求有请求体 2.get请求的参数&#xff08;需要传递的数据&#xff09;要放在URL中发送。大小有限制 post请求的参数可以放在URL后传递&#xff0c;也可以放在请求体中&#xff08;大小不受限制&#xff09…

Jmeter进行http接口测试,这一篇就搞定

jmeter-http接口测试脚本 jmeter进行http接口测试的主要步骤 &#xff08;1.添加线程组 2.添加http请求 3.在http请求中写入接口的URL&#xff0c;路径&#xff0c;请求方式&#xff0c;参数 4.添加查看结果树 5.调用接口&#xff0c;查看返回值&#xff09; 针对接口添加…

http接口测试——Jmeter接口测试实例讲解

一、测试需求描述 1、 本次测试的接口为http服务端接口 2、 接口的主要分成两类&#xff0c;一类提供给查询功能接口&#xff0c;一类提供保存数据功能接口&#xff0c;这里我们举例2个保存数据的接口&#xff0c;因为这两个接口有关联性&#xff0c;比较有代表性&#xff1b;…

http接口测试工具-Advanced-REST-client

非常好用的http接口测试工具 相信作为一个java开发人员&#xff0c;大家或多或少的要写或者接触一些http接口。而当我们需要本地调试接口常常会因为没有一款好用的工具而烦恼。今天要给大家介绍一款非常好用、实用且方便的http接口测试工具。本人认为这是目前我用过的最好http…