opencv创建图像,图像像素值处理、生成单通道图像和生成tif图像方法的整理

就是做个小笔记,后面要查方便

1、创建设定尺寸图象

import numpy as np
"""h,w,c分别代表图像的高、宽和通道数"""
img = np.zeros((h,w,c),dtype = 'uint8')#全为0的图
img = np.zeros((h,w,c),dtype = 'uint8')#全为1的图
"""图像复制"""
img_x= img.copy()
"""查看图像尺寸等信息"""
img.shape
(img.shape[0],img.shape[1],img.shape[2])
img.size
"""通道分离,拆分通道 """
b, g, r = cv2.split(img)
"""合并通道""" 
m = cv2.merge([b, g, r]) 
cv2.imshow("Merge", m) 

2、图像像素值处理

"""像素值为0的像素个数"""
len(img[img == 0])
"""某个通道上"""
img[img[:,:,0] == 0]
img[img[:,:,1] == 0]
"""某个点上的像素值"""
xx = img[h1,w1,c1]#像素坐标+通道
"""该区域设置为白色 ,y表示行的范围,x表示列的范围"""
img[y1:y2, x1:x2]=[255,255,255] 
img[100:200, 150:250] = [255,255,255] 
"""修改像素 """
img[88,142] = [255, 255, 255] 
"""分别获取 BGR通道像素""" 
blue = img[88,142,0] 

3、保存为单通道图像

import cv2
"""三通道bgr转单通道gray"""
img=cv2.imread('breast_img1.png',cv2.IMREAD_GRAYSCALE)
cv2.imwrite('one.png',img)
"""直接获取某通道数据进行保存"""
cv2.imwrite(save_path,img[:,:,0])

4、关于cv2.imwrite()和cv2.imread()

"""cv.imread后加上-1即可,表示按照图片原有格式进行读取如果没有加上-1图片会被自动转换为三通道图片"""
实验验证过,我以png格式保存了(imwrite)单通道的图像,用imread()读取保存的图片发现变成三通道了
用法:
cv2.imread(jpgfile_path,-1)
这样读出来就跟保存时的一致了
retval = imread(filename[, flags]) 

retval = imread(filename[, flags]) filename表示需要载入的图片路径名,其支持 Windows位图、JPEG文件、PNG图片、便携文件格式、Sun rasters光栅文件、TIFF文件、HDR文件等。
flags为 int类型,表示载入标识,它指定一个加载图像的颜色类型,默认值为 1。其中 cv2.IMREAD_UNCHANGED表示读入完整图像或图像不可变,包括 alpha通道;cv2.IMREAD_GRAYSCALE表示读入灰度图像;cv2.IMREAD_COLOR表示读入彩色图像,默认参数,忽略 alpha通道。

retval = imwrite(filename, img[, params]) 

filename表示要保存的路径及文件名

img表示图像矩阵

params表示特定格式保存的参数编码,默认值为空。对于 JPEG图片,该参数(cv2.IMWRITE_JPEG_QUALITY)表示图像的质量,用 0-100的整数表示,默认值为 95。对于 PNG图片,该参数(cv2.IMWRITE_PNG_COMPRESSION)表示的是压缩级别,从 0到 9,压缩级别越高,图像尺寸越小,默认级别为 3。对于 PPM、PGM 、 PBM 图片 ,该参数表示 一个二进制格式的标志(cv2.IMWRITE_PXM_BINARY)[2]。注意,该类型为 Long,必须转换成 int。

5、生成单波段tif图像:

实践总结,便于后续查阅。主要目标是用于生成tif图像,并让处理效果显示在tif图像上。
主要思路:
①根据原始tif图像的相关信息创建一张新的tif,含投影坐标系,经纬度等
②cv方法创建一张图像,本质是数字矩阵,用于操作像素值
③把cv图像的数值赋给tif图像,根据函数配置等生成

import numpy as np
import os
import sys
from osgeo import gdal
import cv2

tif_out_path = './xxx/'
"""如果坐标系信息是继承自原有tif,假设通过一个读取函数gadl_info获取"""
img_width, img_height, img_nbands, img_proj,img_coord,dataset = gdal_info(image_file)
basename = os.path.basename(image_file)[:-4]#获取原图像的名称
tif_pre0 = np.zeros((img_height,img_width,3,dtype = 'uint8')
driver = gdal.GetDriverByName("GTiff")
tif_out_name = tif_out_path + basename + '.tif'
tif_pre = driver.Create(tif_out_name,img_width,img_height,1,gdal.GDT_Byte)
"""上面的“1”表示单波段,gdal.GDT_Byte是tif图像的8位像素深度"""
tif_pre.SetProjection(img_proj)
tif_pre.SetGeoTransform(img_coord)
"""上面两个是投影坐标系继承和坐标继承,左上角坐标值,如果不是继承,发生变化要重新计算"""
cv2.fillPoly(tif_pre0,[area1,area2],(255,255,255))
"""假如对某张cv图像进行区域的像素值填充操作,要把操作效果生成在tif图像上,如下"""
tif_pre.GetRasterBand(1).WriteArray(tif_pre0[:,:,-1])
del tif_pre

如果是生成多波段tif图像,就是通道上读取的数值分顺序写入

"""加入要生成tif波段数为n"""
tif_pre = driver.Create(tif_out_name,img_width,img_height,n,gdal.GDT_Byte)
tif_pre0 = np.zeros((img_height,img_width,3,dtype = 'uint8')
"""如果得到的数字矩阵维度是3,那么按通道写入,显然可以得到波段数n为3的tif图像"""
for i in range(3):
	tif_pre.GetRasterBand(i+1).WriteArray(tif_pre0[:,:,i])
del tif_pre

猜你喜欢

转载自blog.csdn.net/qq_44442727/article/details/127146404
今日推荐