CFAR检测

news/2025/3/16 19:29:20/文章来源:https://www.cnblogs.com/cjming/p/18233742

目标检测:1幅海上SAR图像和1幅近海光学图像,选择其中一幅检测出图像上的舰船(包括停靠码头)目标。

检测步骤

  1. 图像裁剪:把原图裁剪成 448 * 640 的 patch,检测每个小 patch 中的舰船目标。

  2. 读取图像:读取每个图像,并将其转换为灰度图。为了方便处理边缘区域,用补零的方式对图像进行填充。

    初始化参数:设置 虚警率、保护区边长、杂波区环形宽度 等参数。

  3. 遍历图像中的每个点:对于每个点,计算其周围区域的均值和标准差,然后用这两个值来计算一个阈值。如果该点的值大于阈值,就认为该点是目标(用1表示);否则,认为该点是背景(用0表示)。

  4. 形态学处理:对结果进行闭运算、腐蚀和膨胀操作,这些操作可以帮助消除小的噪声,连接断裂的部分,平滑边缘等。使用 ndimage.label 函数标记结果中的连通区域。

  5. 保存结果:将步骤2中添加的填充删除,得到和原图像同样大小的结果并保存。

将图像裁剪成小块

class crop_stitch_images():def __init__(self, overlap=0.1, crop_H=448, crop_W=640, crop_path='./detect/crop_images/'):super(crop_stitch_images, self).__init__()self.overlap = overlapself.crop_path = crop_pathself.crop_num = 0self.crop_H = crop_Hself.crop_W = crop_W# 裁剪图片def crop_image(self, image_path):# 读取图像img = cv2.imread(image_path)H0, W0, C = img.shapeif C != 1:img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 裁剪成几张 H x WH = self.crop_HW = self.crop_Wif H0 < H or W0 < W:print('The image is too small, please check the input parameters')return# 计算裁剪后的图像os.makedirs(self.crop_path, exist_ok=True)for i in range(0, H0, H):for j in range(0, W0, W):start_r = max(0, i - int(H * self.overlap))start_c = max(0, j - int(W * self.overlap))end_r = min(H0, start_r + H)end_c = min(W0, start_c + W)roi = img[start_r:end_r, start_c:end_c]# 不够 H x W 的部分用 0 填充if roi.shape[0] < H or roi.shape[1] < W:roi = cv2.copyMakeBorder(roi, 0, H - roi.shape[0], 0, W - roi.shape[1], cv2.BORDER_CONSTANT, value=0)cv2.imwrite(os.path.join(self.crop_path, image_path[:-4] + '_{}_{}.jpg'.format(start_r, start_c)), roi)self.crop_num += 1

cfar 目标检测的代码如下

class CfarDetector():def __init__(self, width=40, height=45):_width = width_height = heightself.tMaxLength = max(_width, _height)self.proLength = self.tMaxLength * 2 + 1self.cLength = 1self.cfarHalfLength = self.tMaxLength+self.cLengthself.cfarLength = self.proLength + 2 * self.cLengthself.g = Noneself.resultArray = Nonedef densfilt(self, r, c, width, height, densGate):a = np.ceil(height/2)b = np.ceil(width/2)rStart = r - arEnd = r + acStart = c - bcEnd = c + bdensSection = self.resultArray[int(rStart):int(rEnd), int(cStart):int(cEnd)]num = np.sum(densSection)if num >= densGate:value = 1else:value = 0return valuedef getEstSec(self, r, c, method):cs1 = [r - self.cfarHalfLength, c - self.cfarHalfLength, self.cfarLength, self.cLength]cs2 = [r + self.tMaxLength+1, c - self.cfarHalfLength, self.cfarLength, self.cLength]cs3 = [r - self.tMaxLength, c - self.cfarHalfLength, self.cLength, self.proLength]cs4 = [r - self.tMaxLength, c + self.tMaxLength + 1, self.cLength, self.proLength]csIndex1 = [cs1[0], cs1[0]+cs1[3]-1, cs1[1], cs1[1]+cs1[2]-1]csIndex2 = [cs2[0], cs2[0]+cs2[3]-1, cs2[1], cs2[1]+cs2[2]-1]csIndex3 = [cs3[0], cs3[0]+cs3[3]-1, cs3[1], cs3[1]+cs3[2]-1]csIndex4 = [cs4[0], cs4[0]+cs4[3]-1, cs4[1], cs4[1]+cs4[2]-1]return csIndex1, csIndex2, csIndex3, csIndex4def cfarEstPra(self, csIn1, csIn2, csIn3, csIn4):sec1 = self.g[int(csIn1[0]):int(csIn1[1])+1, int(csIn1[2]):int(csIn1[3])+1]sec2 = self.g[int(csIn2[0]):int(csIn2[1])+1, int(csIn2[2]):int(csIn2[3])+1]sec3 = self.g[int(csIn3[0]):int(csIn3[1])+1, int(csIn3[2]):int(csIn3[3])+1]sec4 = self.g[int(csIn4[0]):int(csIn4[1])+1, int(csIn4[2]):int(csIn4[3])+1]sec1 = sec1.flatten()sec2 = sec2.flatten()sec3 = sec3.flatten()sec4 = sec4.flatten()sec = np.concatenate((sec1, sec2, sec3, sec4))u = np.mean(sec)e2 = np.mean(np.square(sec))delta = np.sqrt(e2 - np.square(u))return u, deltadef detect(self, img_path):#读取图像src = cv2.imread(img_path, cv2.IMREAD_GRAYSCALE)print("src shape: ", src.shape)pf = 0.001src = src.astype(np.float64)f_size = src.shapepadLength = self.cfarHalfLengthself.g = np.pad(src, padLength, mode='symmetric')self.resultArray = np.zeros(self.g.shape)numPix = 2*self.cLength * (2 * self.cLength + self.proLength + self.proLength)print('CFAR检测器保护区边长:{},杂波区环形宽度:{},用于杂波的像素数:{}'.format(self.proLength, self.cLength, numPix))th = (2*np.sqrt(-np.log(pf))-np.sqrt(np.pi))/(np.sqrt(4-np.pi))# 遍历图像中的每个点for i in range(padLength, f_size[0]+padLength):for j in range(padLength, f_size[1]+padLength):csIndex1, csIndex2, csIndex3, csIndex4 = self.getEstSec(i, j, 1)u, delta = self.cfarEstPra(csIndex1, csIndex2, csIndex3, csIndex4)temp = (self.g[i,j]-u)/deltaif temp > th:                self.resultArray[i,j] = 1else:self.resultArray[i,j] = 0self.resultArray = self.resultArray[padLength:-padLength, padLength:-padLength]se = morphology.disk(1)resultArray2 = ndimage.binary_closing(self.resultArray, structure=se)resultArray3 = ndimage.binary_erosion(resultArray2, structure=se)resultArray4 = ndimage.binary_dilation(resultArray3, structure=se)resultArray5, num = ndimage.label(resultArray4)# plt.imshow(resultArray5)# plt.show()cv2.imwrite(img_path[:-4] + '_mask.png', resultArray5*255)

近海光学图像 的几个图像区域的检测结果如下:

在海中行驶的船只检测效果较好,而停靠在码头的目标检测比较困难,尤其是一些大型船只。

**海上 SAR 图像 **的几个图像区域的检测结果如下:

同样的,在海中行驶的船只检测效果较好,而停靠在码头的目标由于背景相对比较复杂,检测比较困难,但是这种检测方法可以避免杂波背景起伏变化的干扰,几乎可以检测到所有海洋中的目标。

为了提高检测的精度,可以尝试调节参数,在开阔海域增大虚警率,增大检测率的同时虚警率不会有较大改变;对岸边的 patch 小的虚警率效果较好。

最后在原始的大图上绘制检测框

def draw_box(ori_img, bw, h, w, start_h, start_w):# 找到所有连续的白色区域bw = bw > 0labels = measure.label(bw)regions = measure.regionprops(labels)# 获取每个区域的边界框bounding_boxes = [region.bbox for region in regions]bounding_boxes = [(x1, y1, x2, y2) for (y1, x1, y2, x2) in bounding_boxes]# 在图像上画出每个边界框for bbox in bounding_boxes:x1, y1, x2, y2 = bboxif abs(x1-x2) * abs(y1-y2) < 10:	# 可见光图像设为 30continueori_img = cv2.rectangle(ori_img, (start_w+x1, start_h+y1), (start_w+x2, start_h+y2), (0, 255, 0), 2)    return ori_img

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

内网穿透详细教程

内网穿透详细教程 本文介绍如何使用 FRP(Fast Reverse Proxy)工具实现内网穿透,包括配置 Azure 公网 IP、安装 Docker 和 FRP,以及在内网服务器上配置和运行 FRP 客户端。 一、配置公网 IP 1. 申请 Azure 公网 IP登录到 Azure 门户。 创建一个新的虚拟机实例,建议使用1G内…

兴达易控232自由转profinet网关接扫码枪配置及测试案例

232自由口转Profinet网关(XD-PNR100/300)的主要功能就是将具有RS232接口的设备(如扫码枪、打印机、传感器等)接入到Profinet网络中,从而实现了传统设备与现代化工业以太网之间的无缝通信和数据交换。兴达易控232自由口转profinet网关接扫码枪配置及测试案例 232自由口转Pr…

杭州出租车行驶轨迹数据空间时间可视化分析|附代码数据

原文链接:http://tecdat.cn/?p=7324 最近我们被客户要求撰写关于出租车的研究报告,包括一些图形和统计输出 城市化带来的道路拥堵、出行耗时长等交通问题给交管部门带来了巨大的挑战 ▼ 通过安装在出租车上的GPS设备,可以采集到大量的轨迹数据,从而帮助我们分析人们出行信…

【专题】2024客户端游戏市场营销发展报告合集PDF分享(附原数据表)

原文链接:https://tecdat.cn/?p=36402 原文出处:拓端数据部落公众号 报告合集显示,中国客户端游戏市场在2023年创新高,达到662.83亿元,表明精品化和跨端生态趋势对市场的推动作用。报告合集强调客户端游戏的独特优势,如精品内容、视听体验和操作反馈等,促进了市场稳定增…

BD202404 110串

百度之星一场,t4 题目链接: 对于这种连续状态限制的字符串方案数,首先考虑dp, 首先定义好每个状态方便转移,0状态是结尾为0,1状态是结尾1个连续1,2状态是结尾两个连续1,有以下关系if(s[i] == 1) {if(j > 0) dp[i][j][0] = (dp[i][j][0] + dp[i - 1][j - 1][0] + dp[…

Vue 3 Teleport:掌控渲染的艺术

title: Vue 3 Teleport:掌控渲染的艺术 date: 2024/6/5 updated: 2024/6/5 description: 这篇文章介绍了Vue3框架中的一个创新特性——Teleport,它允许开发者将组件内容投送到文档对象模型(DOM)中的任意位置,即使这个位置在组件的挂载点之外。Teleport旨在解决某些特定场景…

如何解决无法解析 JSP 中的方法 getParameter()

在构建JSP项目中,出现无法解析 JSP 中的方法 getParameter()的错误 1、右键单击您的项目并选择Open Module Settings,确保您在Modules部分的Dependencies选项卡上,单击底部的“+”按钮,然后选择1 JAR 或目录...:2、将apache-tomcat-8.5.31servlet-api.jar部署到容器中,点…

基于c语言的TCP客户端、服务端基础代码

基于c语言的TCP客户端、服务端基础代码 基本流程:客户端:#include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <stdio.h> #include <errno.h> #include <sys/socket.h> #include <netinet/in.h> #i…

解决错误运行‘Tomcat 9.0.35‘: 地址 localhost:1099 已在使用

“Error running ‘Tomcat 9.0’: Address localhost:1099 is already in use”报错问题问题描述:idea运行项目时,左下方出现红色小方块提示问题“Error running ‘Tomcat 9.0’: Address localhost:1099 is already in use”。 这是因为端口被占用了。 解决问题: 按win+R打…

嵌入式 Linux LED 驱动开发实验学习

I.MX6U-ALPHA 开发板上的 LED 连接到 I.MX6ULL 的 GPIO1_IO03 这个引脚上,进行这个驱动开发实验之前,需要了解下地址映射。 地址映射 MMU 全称叫做 MemoryManage Unit,也就是内存管理单元。在老版本的 Linux 中要求处理器必须有 MMU,但是现在 Linux 内核已经支持无 MMU 的处…

囚徒5.4_基于texlive的PlotNeuralNet画深度学习框架图

首先下载并安装texlive 连接如下texlive安装教程 接着下载PlotNeuralNet项目 下载链接PlotNeuralNet对PlotNeuralNet的一些解释它其实是基于texlive语言,然后通过python语言按照texlive的语法格式进行拼接生成tex文档之后使用pdflatex命令生成pdf. PlotNeuralNet中有一系列的写…

第二次大作业BLOG心得

(1)前言: 知识点: ①ArrayLsit的知识点: ArrayList 是 Java 中的动态数组实现,它提供了自动调整大小的功能,可以根据需要动态增长或收缩。 ArrayList 可以存储任意类型的对象,并支持随机访问,即可以通过索引快速访问列表中的元素。 ArrayList 内部通过数组实现,当元素…