类似四边形轮廓获取顶点坐标

本文介绍了一种使用OpenCV库进行图像处理的方法,通过二值化、轮廓查找及近似多边形处理,实现从图像中提取目标轮廓并定位其顶点位置,最后将顶点在新图像上进行可视化展示。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

std::vector<cv::Point> GetVertex(cv::Mat src)
{
	Mat img;
	src.copyTo(img);
	threshold(img, img, 200, 255, CV_THRESH_BINARY);

	std::vector<std::vector<cv::Point>> point;
	vector<Vec4i>g_vHierarchy1;//层次结构信息
	findContours(img, point, g_vHierarchy1, RETR_CCOMP, CHAIN_APPROX_NONE, Point(0, 0));
 	std::vector<cv::Point> vertex_point;
 	cv::Mat paint1(img.size(), CV_8UC3, cv::Scalar(0, 0, 0));
 	auto i = point.begin();
 	approxPolyDP(*i, vertex_point, 7, 1);
 	for (auto a : vertex_point)
        {
            cv::circle(paint1, a, 2, cv::Scalar(0, 0, 255));
        }
 		
 	cv::imshow("roi_approx", paint1);

 	waitKey(0);

	return vertex_point;
}

原图: 结果图:

 

首先,代码通过MaixPy库初始化了摄像头(设置分辨率为320x240)、显示屏以及串口通信。 同时,导入了OpenCV库(cv2)和NumPy库,以便进行图像处理。 2. 图像处理流程 从摄像头读取一帧图像,并对图像进行镜头畸变校正。 将图像从MaixPy的图像格式转换为OpenCV的图像格式,以便进行后续的OpenCV处理。 将图像转换为灰度图,以减少处理的数据量并提高处理速度。 对灰度图应用双边滤波器,以减少噪声并保留边缘信息。 使用形态学操作(闭运算)来填充图像中的小孔洞,并连接邻近的物体。 应用Canny边缘检测算法来检测图像中的边缘。 使用findContours函数查边缘连接成的轮廓。 3. 形状识别与坐标发送 对于每个检测到的轮廓,代码调用process_shape函数来识别其形状并获取轮廓顶点坐标。 在process_shape函数中,首先使用cv2.approxPolyDP函数来近似轮廓的形状,并根据轮廓的数量来判断形状(三形、四边形、五边形、六边形)。 识别到的形状名称和顶点坐标会在控制台打印出来。 同时,顶点坐标会被发送到串口。在发送之前,坐标值会被限制在0到255的范围内,以满足串口通信的数据格式要求。 4. 显示处理后的图像 最后,将处理后的图像(带有形状轮廓顶点标记的图像)从OpenCV的图像格式转换回MaixPy的图像格式,并在显示屏上显示。 5. 循环处理 整个图像处理流程在一个无限循环中进行,以便持续从摄像头读取图像并进行处理。 请根据这个流程及要求用maixcam基于maixpy写一份可以准确识别多边形且能返回多边形各个顶点坐标的代码
07-26
import sensor, image, time from machine import UART #串口库函数 from fpioa_manager import fm # GPIO重定向函数 # 初始化摄像头 - 降低分辨率并跳过更多预热帧 sensor.reset() sensor.set_pixformat(sensor.GRAYSCALE) # 使用灰度图像减少处理量 sensor.set_framesize(sensor.QQVGA) # 从QQVGA(160x120)降为QQQVGA(80x60) sensor.skip_frames(time=1000) # 减少预热时间 sensor.set_auto_gain(False) # 关闭自动增益以提升帧率 sensor.set_auto_whitebal(False) # 关闭白平衡提升速度 fm.register(7, fm.fpioa.UART1_TX, force=True) uart_A = UART(UART.UART1, 115200, 8, 0, 1, timeout=1000, read_buf_len=4096) HEADER = b'$' # 包头 '$' FOOTER = b'#' # 包尾 '#' # 颜色定义(OpenMV使用RGB格式) RED = (255, 0, 0) GREEN = (0, 255, 0) BLUE = (0, 0, 255) YELLOW = (255, 255, 0) def detect_outer_rectangle(img): """优化矩形检测算法""" # 使用更高效的阈值和面积过滤 rects = img.find_rects(threshold=3000) # 提高阈值减少检测数量 if not rects: return None # 直接查最大矩形避免遍历所有结果 max_rect = max(rects, key=lambda r: r.w() * r.h()) # 添加宽高比快速过滤 aspect_ratio = max_rect.w() / max_rect.h() if not (0.8 < aspect_ratio < 1.2): # 限制为近似正方形 return None return max_rect def send_packet(x, y): data_str = "[{},{}]".format(int(x), int(y)) # 组合成完整包: $ + 数据 + # packet = HEADER + data_str + FOOTER # 完整包: $[x,y]# packet_bytes = packet.decode('utf-8') uart_A.write(packet_bytes) def process_frame(img): """处理单帧图像(对应OpenCV的process_frame函数)""" img_width = img.width() img_height = img.height() # 计算图像中心(对应OpenCV的img_center_x, img_center_y) img_center_x, img_center_y = img_width // 2, img_height // 2 # 识别外边框 best_rect = detect_outer_rectangle(img) # 显示识别状态 status_text = "none" status_color = RED if best_rect is not None: status_text = "have" status_color = GREEN center_x, center_y = best_rect.rect()[0] + best_rect.rect()[2] // 2, best_rect.rect()[1] + best_rect.rect()[3] // 2 if center_x>10 and center_y>10 and center_x<150 and center_y<100: x=img.get_statistics(roi=(center_x, center_y,4,4)).mean() if x>120: img.draw_rectangle(best_rect.rect(), color=(255, 0, 0), thickness=2) img.draw_circle(center_x, center_y, 3, color=RED, fill=True) print("中坐标: ({}, {})".format(center_x, center_y)) # 发送数据 send_packet(center_x, center_y) def main(): clock = time.clock() frame_count = 0 while True: clock.tick() img = sensor.snapshot() # 获取一帧图像(对应cv2.VideoCapture.read) processed_img = process_frame(img) if __name__ == "__main__": main() 参考下列方法:1.转为二值化图像。2.适当减少曝光时间。3.使用灰度图像。4.采用轻量级模型。5.先通过边缘检测提取矩形轮廓;再用轮廓逼近筛选出四边形轮廓;最后通过面积、长宽比等特征过滤非矩形轮廓,确定目标后计算中心轮廓顶点坐标平均)。提高摄像头识别目标的准确率和速度
最新发布
08-03
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值