OpenCV自带例子(二)Load, Modify, and Save an Image

本文介绍了一个使用C++和OpenCV实现的简单程序,该程序可以加载图像、将其从RGB格式转换为灰度格式,并将转换后的图像保存到磁盘上。此外,程序还展示了如何使用OpenCV显示原始图像及其灰度版本。

Load, Modify, and Save an Image

Goals:


In this tutorial you will learn how to:

Load an image using imread

Transform an image from RGB to Grayscale format by using cvtColor

Save your transformed image in a file on disk (using imwrite)


#include <cv.h>
#include <highgui.h>
using namespace cv;
int main( int argc, char** argv )
{
	char* imageName = argv[1];

	Mat image;
	image = imread( imageName, 1 );
	if( argc != 2 || !image.data )
	{
		printf( " No image data \n " );
		return -1;
	}
	Mat gray_image;
	cvtColor( image, gray_image, CV_RGB2GRAY );
	imwrite( "../../images/Gray_Image.jpg", gray_image );
	namedWindow( imageName, CV_WINDOW_AUTOSIZE );
	namedWindow( "Gray image", CV_WINDOW_AUTOSIZE );
	imshow( imageName, image );
	imshow( "Gray image", gray_image );
	waitKey(0);
	return 0;
}


import rospy import rosbag from std_msgs.msg import String from datetime import datetime from hikai_msgs.msg import DetectedObjectArray from hikai_msgs.msg import DetectedObject import geometry_msgs.msg import json import cv2 import os import numpy as np from geopy.distance import geodesic import math from pyproj import Proj, transform import tifffile as tf polygon = np.array([[955,382],[965,359],[797,342],[928,195],[1046,116],[1211,128],[1179,203],[1159,378]], dtype=np.int32) def get_utm_zone(longitude): return int((longitude + 180) // 6 + 1) def utm_to_gps(easting, northing, zone_number, zone_letter="N"): utm_proj = Proj(proj="utm", zone=zone_number, ellps="WGS84", south=(zone_letter == "S")) lon, lat = utm_proj(easting, northing, inverse=True) return lon, lat def modify_msg(msg): for i in range(len(msg.objects)-1,-1,-1): device_id = msg.objects[i].sensor_source.device_id if device_id not in map_tiff: continue img_tf_x = map_tiff[device_id]['img_tf_x'] img_tf_y = map_tiff[device_id]['img_tf_y'] zone_n = get_utm_zone(img_tf_y[0,0]) xmin = msg.objects[i].camera_sup.box.xmin xmax = msg.objects[i].camera_sup.box.xmax x = int((xmin + xmax) / 2.0) y = int( msg.objects[i].camera_sup.box.ymax) # point = (x,y) # if device_id == '192.168.11.16' and cv2.pointPolygonTest(polygon, point, False) > 0: # msg.objects[i].camera_sup.box.ymax = msg.objects[i].camera_sup.box.ymax - 2 # y = y - 2 utm_x = img_tf_x[y,x] utm_y = img_tf_y[y,x] if utm_x !=0 and utm_y!=0: lon, lat = utm_to_gps(utm_x, utm_y, zone_n) msg.objects[i].global_pose.x = lon msg.objects[i].global_pose.y = lat msg.objects[i].utm.x = utm_x msg.objects[i].utm.y = utm_y else: del msg.objects[i] map_tiff = dict() def load_tiff(tiff_dir): tiff_files = os.listdir(tiff_dir) for tiff in tiff_files: ip = os.path.splitext(tiff)[0] tiff_path = os.path.join(tiff_dir,tiff) img_tf_x = tf.imread(tiff_path,series=0) img_tf_y = tf.imread(tiff_path,series=1) img_tf = dict() img_tf['img_tf_x'] = img_tf_x img_tf['img_tf_y'] = img_tf_y map_tiff[ip] = img_tf bag_dir = '/home/data/label_group/aichengjie/bag/' tiff_dir ='/home/data/label_group/aichengjie/tiff/test/' topic_list = ['/127_0_0_1/camera_debug/192_168_1_165','/127_0_0_1/camera_debug/192_168_1_167','/127_0_0_1/camera_debug/192_168_1_177','/127_0_0_1/camera_debug/192_168_1_178','/127_0_0_1/camera_debug/192_168_1_188',\ '/127_0_0_1/camera_debug/192_168_1_190','/127_0_0_1/camera_debug/192_168_1_192','/127_0_0_1/output/image_msg'] save_dir = '/home/data/label_group/tool/scripts/correct_gps/output/' load_tiff(tiff_dir) rospy.init_node('test_node', anonymous=True) bag_list = os.listdir(bag_dir) bag_list = [bag_file for bag_file in bag_list if bag_file[-4:] == '.bag'] for bag_name in bag_list: print(bag_name) bag = rosbag.Bag(bag_dir + bag_name) bag_save = rosbag.Bag(save_dir + bag_name, 'w') num = 0 for topic, msg, t in bag.read_messages(): num += 1 # if num > 100: # break if topic in topic_list: modify_msg(msg) bag_save.write(topic, msg, t) bag_save.close()
最新发布
07-23
<think>我们有一个ROS节点,它读取rosbag文件,对特定话题的消息进行修改,然后将修改后的消息写入新的rosbag文件。 具体来说,代码做了以下事情: 1. 定义了一个多边形区域(用于某个特定设备ID的过滤,但当前注释掉了)。 2. 定义了两个坐标转换函数:get_utm_zone(根据经度计算UTM区域)和utm_to_gps(将UTM坐标转换为GPS坐标)。 3. 定义了一个modify_msg函数,该函数处理DetectedObjectArray消息: - 遍历消息中的每个对象(倒序遍历,以便在需要时删除)。 - 根据设备ID在全局字典map_tiff中查找对应的tiff图像数据(包含x和y方向的坐标映射)。 - 如果设备ID不存在,则跳过该对象。 - 从对象中获取2D边界框的中心x和底部y坐标(注意:有一行被注释的代码,用于对特定设备ID和特定多边形区域内的点进行y坐标调整)。 - 使用tiff图像中对应位置的坐标值(utm_x, utm_y)作为UTM坐标,然后转换为经纬度(GPS坐标)。 - 如果转换成功(utm_x和utm_y都不为0),则更新对象的全局姿态(经纬度)和UTM坐标;否则,删除该对象。 4. 加载tiff文件:遍历指定目录下的所有tiff文件,将每个文件(以IP地址命名)的两个通道(series0和series1)分别作为x和y坐标的映射,存储在map_tiff字典中,键为IP地址(不带后缀)。 5. 初始化ROS节点(尽管这里没有使用ROS的功能,但读取rosbag不需要节点,可能是为了其他目的?)。 6. 遍历指定目录下的所有bag文件,对每个bag文件: - 打开并读取每个消息。 - 如果消息的话题在指定的topic_list中,则调用modify_msg修改消息内容。 - 将修改后的消息写入新的bag文件。 注意:代码中有一个多边形区域(polygon)和一个被注释的条件判断(针对设备ID为'192.168.11.16'且点在该多边形内的情况),目前该部分不生效。 但是,我们注意到代码中有一个问题: 在modify_msg函数中,我们使用以下方式获取tiff图像中的坐标: utm_x = img_tf_x[y,x] utm_y = img_tf_y[y,x] 注意:数组索引是[y,x],而y是从图像顶部到底部,但OpenCV中图像坐标的原点在左上角。然而,在计算机视觉中,我们通常用行(y)和列(x)来索引。这里我们直接使用边界框的坐标(x,y)作为图像的列和行,所以这样索引是合理的。 但是,我们需要注意:tiff图像数据中的坐标映射关系是否正确?以及坐标原点在哪里?这取决于生成tiff文件时的设置。 另一个潜在问题:在utm_to_gps函数中,我们假设了北半球(zone_letter="N"),因为代码中写死了“N”。如果处理的数据位于南半球,则会出现问题。不过,根据使用场景,这里可能默认处理北半球的数据。 此外,代码中加载tiff文件时,使用文件名作为设备ID(IP地址),而消息中的设备ID是字符串,所以需要确保格式一致。例如,消息中的设备ID可能是'192.168.1.165',而tiff文件名为'192.168.1.165.tiff',则使用文件名去掉后缀作为键,所以是匹配的。 但是,请注意topic_list中的话题名称包含的IP地址(如192_168_1_165)与tiff文件名的IP地址(192.168.1.165)不同,因为话题中使用了“_”代替“.”。然而,在modify_msg函数中,我们是从msg.objects[i].sensor_source.device_id获取设备ID,这个设备ID应该是包含“.”的,因为它是字符串。因此,我们需要确保tiff文件名的IP地址与这个device_id字符串一致(即使用“.”分隔)。在load_tiff函数中,我们使用文件名(不带后缀)作为键,所以如果tiff文件名是“192.168.1.165.tiff”,那么键就是“192.168.1.165”。而消息中的device_id应该也是“192.168.1.165”这样的格式,所以可以匹配。 因此,代码逻辑基本正确。 但是,我们注意到topic_list中有一个话题不是以IP地址结尾的:'/127_0_0_1/output/image_msg'。这个消息话题中的消息会被修改,但是modify_msg函数中会检查每个对象的设备ID是否在map_tiff中。由于map_tiff的键是tiff文件的名称(IP地址),所以如果消息中的设备ID不是这些IP地址,那么这些对象就会被跳过(不修改,但也不会被删除,除非不在map_tiff中且需要修改?)。注意,modify_msg函数中,如果设备ID不在map_tiff中,会跳过该对象(不做处理,但也不删除)。所以,对于不在map_tiff中的设备ID,该对象不会被删除,也不会被修改,而是原样保留。 另外,在modify_msg中,如果utm_x和utm_y都为0,则删除该对象。这是因为0值可能表示无效位置(tiff图像中可能用0表示无数据)。 最后,代码处理每个bag文件时,会读取所有消息,修改指定话题的消息,然后写入新的bag文件。其他话题的消息则原样写入。 现在,根据要求,在回答后提出3-5个相关问题。 注意:回答完毕,最后必须输出“§§相关问题§§”,然后列出相关问题。 由于用户要求用中文回答,所以以下回答和问题均为中文。</think>这段代码实现了一个ROS节点,用于处理包含目标检测数据的rosbag文件。主要功能是通过地理坐标转换修正目标物体的GPS位置,核心流程如下: 1. **初始化配置** - 定义多边形区域`polygon`用于特殊处理(当前被注释) - 加载所有TIFF地理坐标映射文件到`map_tiff`字典(Key=设备IP,Value=UTM坐标映射矩阵) 2. **坐标转换核心逻辑** (`modify_msg`函数) - 倒序遍历检测目标(便于删除无效目标) - 根据设备IP获取对应的UTM坐标映射矩阵 - 计算目标边界框底边中心点坐标(x,y) - 从TIFF映射矩阵获取对应位置的UTM坐标 - 将UTM坐标转换为GPS经纬度: ```python lon, lat = utm_to_gps(utm_x, utm_y, zone_n) ``` - 若坐标无效(0值)则删除目标 3. **批量处理rosbag** - 遍历输入目录下所有bag文件 - 对指定topic的消息应用坐标修正 - 将修正后的数据写入新bag文件 **关键地理转换函数** - `get_utm_zone()`:根据经度计算UTM分区 - `utm_to_gps()`:通过pyproj库实现UTM到WGS84的坐标转换
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值