您的位置:首页 > 运维架构

opencv对遥感图像基本操作

2017-11-09 14:36 453 查看
参考:http://blog.csdn.net/wc781708249/article/details/78485415

1、python版

说明:

数据类型:原类型16bit 4波段 (CV_16UC4),转成32float(CV_32FC4)处理,处理完成后保存成CV_16UC4

1.1绘图与写文本

# 画图
dst=cv2.line(img,(0,0),(2000,2000),(255,0,0),5,cv2.LINE_AA) # 画线
dst = cv2.rectangle(dst,(384,0),(510,128),(0,255,0),3) # 画矩形
dst = cv2.circle(dst,(447,63), 63, (0,0,255), -1) # -1 表示填充
dst = cv2.ellipse(dst,(256,256),(100,50),0,0,180,255,-1)  # 这里的255 相当于(255,0,0)

# 画多边形
pts = np.array([[10,5],[20,30],[70,20],[50,10]], np.int32)
pts = pts.reshape((-1,1,2))
dst = cv2.polylines(dst,[pts],True,(0,255,255),3)

# 写入文字
font = cv2.FONT_HERSHEY_SIMPLEX # 字体
cv2.putText(dst,'OpenCV',(10,256), font, 4,(255,255,255),2,cv2.LINE_AA)
# ----------------------------------------------------------


1.2 分割和合并图像通道

# 分割和合并图像通道
b,g,r = cv2.split(img)
img = cv2.merge((r,g,b)) # BGR转成RGB 针对3个波段的
# or
b=img[:,:,0]
g=img[:,:,1]
r=img[:,:,2]
img2 = cv2.merge((r,g,b))

# 多于3个波段
n_data=cv2.split(img)
dst=cv2.merge((n_data[0],n_data[1],n_data[2])) # 这里只合并前3个波段


1.3 制作边框图像

# 制作边框图像
dst=cv2.copyMakeBorder(img,100,100,100,100,cv2.BORDER_CONSTANT,value=(255,0,0))

replicate = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REPLICATE)
reflect = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT)
reflect101 = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_REFLECT_101)
wrap = cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_WRAP)
constant= cv2.copyMakeBorder(img,10,10,10,10,cv2.BORDER_CONSTANT,value=(255,0,0))


1.4 访问

# 访问和修改像素值
px = img[100,100] # 访问像素值
img[100,100] = [255,255,255] # 修改像素值

img.item(10,10,2) # 访问像素值
img.itemset((10,10,2),100) # 修改像素值

# 访问图像属性
img.shape # [h,w,c]
img.size # h*w*c
img.dtype # float32
type(img) # numpy array

# 图像ROI
ball = img[280:340, 330:390]
img[273:333, 100:160] = ball

# 类型转换
img.astype(np.float32)

# 计算耗时
e1 = cv2.getTickCount()
# your code execution
e2 = cv2.getTickCount()
time = (e2 - e1)/ cv2.getTickFrequency()


1.5 图像算术运算

# 图像加法
dst=cv2.add(img,img)

# 图像混合
dst = cv2.addWeighted(img,0.7,img,0.3,0)

# 按位操作
cv2.bitwise_not()
cv2.bitwise_and()
cv2.bitwise_or()
cv2.bitwise_xor()


1.6 阈值处理

# 简单的阈值
ret,dst = cv2.threshold(img,np.mean(img)*1.5,np.max(img),cv2.THRESH_BINARY)
cv2.THRESH_BINARY
cv2.THRESH_BINARY_INV
cv2.THRESH_TRUNC
cv2.THRESH_TRUNC
cv2.THRESH_TOZERO_INV

# 自适应阈值
dst = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_MEAN_C,\
cv2.THRESH_BINARY,11,2)

# Otsu's thresholding after Gaussian filtering
blur = cv2.GaussianBlur(img,(5,5),0)
ret3,th3 = cv2.threshold(blur,0,255,cv2.THRESH_BINARY+cv2.THRESH_OTSU)


1.7图像的几何变换

# 缩放
dst = cv2.resize(img,None,fx=2, fy=2, interpolation = cv2.INTER_CUBIC) # h,w放大2倍

height, width = img.shape[:2]
dst = cv2.resize(img,(2*width, 2*height), interpolation = cv2.INTER_CUBIC) # h,w放大2倍

# 平移
rows,cols = img.shape[:2]
M = np.float32([[1,0,100],[0,1,50]])
dst = cv2.warpAffine(img,M,(cols,rows))

# 旋转
M = cv2.getRotationMatrix2D((cols/2,rows/2),90,1) # 逆时针旋转90度
dst = cv2.warpAffine(img,M,(cols,rows))

# 仿射变换
pts1 = np.float32([[50,50],[200,50],[50,200]])
pts2 = np.float32([[10,100],[200,50],[100,250]])
M = cv2.getAffineTransform(pts1,pts2)
dst = cv2.warpAffine(img,M,(cols,rows))

# 透视转换
pts1 = np.float32([[56,65],[368,52],[28,387],[389,390]])
pts2 = np.float32([[0,0],[300,0],[0,300],[300,300]])
M = cv2.getPerspectiveTransform(pts1,pts2)
dst = cv2.warpPerspective(img,M,(300,300))

# 重新映射
map_x=np.zeros(img.shape[:2],np.float32)
map_y=np.zeros(img.shape[:2],np.float32)

for j in range(img.shape[0]):
for i in range(img.shape[1]):

# 将图片缩小一半,并将其显示在中间:
if i>img.shape[1]*0.25 and i<img.shape[1]*0.75 and j>img.shape[0]*0.25 and j<img.shape[0]*0.75:
map_x[j,i]=2*(i-img.shape[1]*0.25)+0.5
map_y[j,i]=2*(j-img.shape[1]*0.25)+0.5
else:
map_x[j,i]=0
map_y[j,i]=0

# 上下翻转图像
map_x[j,i]=i
map_y[j,i]=img.shape[0]-j

# # 左右对调
map_x[j,i]=img.shape[1]-i
map_y[j,i]=j

# # 结合上下翻转和左右对调
map_x[j,i] = img.shape[1] - i
map_y[j,i] = img.shape[0] - j

dst=cv2.remap(img, map_x, map_y, cv2.INTER_LINEAR,None, cv2.BORDER_CONSTANT, (0, 0, 0))


1.8 图像平滑

# 二维卷积
kernel = np.ones((5,5),np.float32)/25
dst = cv2.filter2D(img,-1,kernel)

# 均值滤波
dst=cv2.blur(img,(5,5))

# 高斯滤波
dst=cv2.GaussianBlur(img,(5,5),0)

# 中值滤波
dst=cv2.medianBlur(img,5)

# 双边过滤
dst=cv2.bilateralFilter(img,9,75,75)


1.9 形态操作

# 腐蚀
kernel = np.ones((5,5),np.uint8)
dst = cv2.erode(img,kernel,iterations = 1)

# 膨胀
kernel = np.ones((7,7),np.uint8)  # 内核
erosion = cv2.erode(img,kernel,iterations = 1)  # 腐蚀去除噪声
dst = cv2.dilate(erosion,kernel,iterations = 1) # 膨胀恢复原形状


2、C++版

说明:

数据类型:原类型16bit 4波段 (CV_16UC4)(不转成32float(CV_32FC4)处理 ,转float32处理完保存图像会出现各种问题),直接使用原格式处理,处理完成后保存成CV_16UC4

2.1绘图与写文本

//////////////////////////////////////////////////////
/*画图*/
//Mat dst;//输出Mat
line(img, Point(0, 200), Point(1000, 1000), Scalar(0, 0, 0), 2, LINE_8);//画线
circle(img, Point(200, 200), 30, Scalar(0, 0, 255), FILLED, LINE_8);
ellipse(img,Point(100, 100),Size(50, 50),90,0,360,Scalar(255, 0, 0),2,LINE_AA);
rectangle(img,Point(0, 7 * w / 8),Point(w, w),Scalar(0, 255, 255),FILLED,LINE_8);
fillPoly(img,ppt,npt,1,Scalar(255, 255, 255), LINE_8);

putText(img, "Testing text rendering", org, rng.uniform(0, 8),
rng.uniform(0, 100)*0.05 + 0.1, randomColor(rng), rng.uniform(1, 10), LINE_8);

/////////////////////////////////////////////////////


2.2 分割和合并图像通道

std::vector<cv::Mat> imgMat(St.nbands);
std::vector<cv::Mat> tempMat(St.nbands);
cv::split(img, imgMat); //分离通道
tempMat.at(0) = (imgMat.at(2));//BGR-->RGB
tempMat.at(1) = (imgMat.at(1));
tempMat.at(2) = (imgMat.at(0));
Mat img2;
cv::merge(tempMat, img2);// 合并通道
imgMat.clear();
tempMat.clear();


附加类型转换

img.convertTo(dst, CV_32FC4); //转成32F类型


2.3 制作边框图像

Mat dst;
int top, bottom, left, right;
top = (int)(0.05*img.rows); bottom = (int)(0.05*img.rows);
left = (int)(0.05*img.cols); right = (int)(0.05*img.cols);

copyMakeBorder(img, dst, 50, 50, 50, 50, BORDER_CONSTANT, Scalar(255, 0, 0));


2.4 访问

//img类型为Mat
//ROI
Mat D(img, Rect(10, 10, 100, 100)); // using a rectangle
Mat E = img(Range::all(), Range(1, 3)); // using row and column boundaries

//复制
Mat F = img.clone();
Mat G;
img.copyTo(G);

img.channels(); //通道数
img.rows;//行数 ysize
img.cols;//列数 xsize
img.data;//获取img中所有像素值

CV_Assert(img.depth() == CV_8U);//判断数据类型

//访问像素
img.at<Vec3b>(y, x);
img.at<Vec3b>(Point(x, y));
uchar* p = img.ptr();
p[10];

//修改像素值
img.at<uchar>(y, x) = 128;

Vec3f intensity = img.at<Vec3f>(y, x);
float blue = intensity.val[0];
float green = intensity.val[1];
float red = intensity.val[2];

//计算耗时
double t = (double)getTickCount();
// do something ...
t = ((double)getTickCount() - t) / getTickFrequency();
cout << "Times passed in seconds: " << t << endl;

//类型数据转换
img.convertTo(img,CV_32FC4);


2.5 图像算术运算

beta = (1.0 - alpha);
addWeighted(src1, alpha, src2, beta, 0.0, dst);


2.6 阈值处理

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: