1.1图像存储格式转换
选择一张图片original.jpg
新建一个它的副本命名为副本.jpg用以操作并通过Photoshop打开
在文件一栏选择导出-导出为选项
选择以PNG格式导出
图像存储格式转换成功,导出图像为
1.2图像缩放
打开副本图像,在图像栏选择工具图像大小
调整图像的尺寸,调整宽度与高度将其缩小,默认情况下宽高比已锁定
将其导出
导出图像为
放大同理,在图像大小中调整宽度与高度
放大后图像为
1.3图像的加减
以副本图像为背景,选择文件栏-置入嵌入对象,选择一张纯蓝色的图片
调整嵌入图像的方位
单击嵌入的纯蓝色图层,设置嵌入的混合模式属性为-叠加
然后导出,导出图片如下
继续设置蓝色图层嵌入的混合模式属性,设置为-减去
减去后效果如下
1.4图像的反色
打开副本文件,在图像栏选择调整-反相
得到的便是图像的反色
1.5图像对比度调整
打开副本,在图像栏选择-调整-亮度/对比度
调整对比度数值
将对比度增大后图像如下
任务二:在Matlab、C++、Python语言中选用两种编程实现:读入、存储、显示bmp格式的图像,并展示图像直方图。
MATLAB语言
为了显示方便我将不同深度图片的操作从条件判断中抽取出来分别罗列,下面为每一深度图片的操作说明,将所有程序顺序链接就是总程序,并且我在其中设置了操作提示符,方便阅读时按下回车后再进行下一深度图片的操作
显示的图片 直方图
程序说明:1位深度的图片以及4位、8位都存在的难点是在读取图片数据后进行矩阵的构造时宽度需要做4位字节的修正,MATLAB方便之处在于可以使用fread(bmp,'ubit1')直接进行按位的读取,按1bit读取后0和1分别表示黑和白,再将1转化为255即可对像素进行操作得到图像,再使用imshow函数和imwrite函数进行图像的显示和存储,对于1bit的图片可以直接使用bar画出直方图
input('我们先从1位bmp开始,请按回车')
bmp=fopen('1.bmp');%打开文件
type=fread(bmp,2,'char');%位图类别
bmpsize=fread(bmp,1,'long');%文件大小
bfReserved1and2=fread(bmp,1,'long');
bfOffBits=(fread(bmp,1,'long'));%图像数据地址
biSize=fread(bmp,1,'long');%结构体大小
biWidth=fread(bmp,1,'long');%像素宽
biHeight=fread(bmp,1,'long');%像素高
biPlanes=fread(bmp,1,'short');
biBitCount=fread(bmp,1,'short');%像素深度,下面用来判断
biCompression=fread(bmp,1,'long');%压缩方式
biSizeImage=fread(bmp,1,'long');%像素数据大小,是4的倍数
biXPelsPerMeter=fread(bmp,1,'long');%水平分辨率
biYPelsPerMeter=fread(bmp,1,'long');%垂直分辨率
biClrUsed=fread(bmp,1,'long');
biClrImportant=fread(bmp,1,'long');
fclose(bmp);
if biBitCount==1%判断此确实是1bit的图
bmpsize=8*bmpsize;%从byte到bit的修正
bfOffBits=8*bfOffBits;
biSizeImage=8*biSizeImage;
bmp=fopen('1.bmp','rb');%重新打开文件读入
[data,count]=fread(bmp,'ubit1');%以1bit为单位读入
img=reshape(data(bfOffBits+1:bfOffBits+biHeight*(ceil(biWidth/32))*32),biWidth+20,biHeight);
%上面将图像像素重新排成宽度*高度的矩阵
img=logical(img);%转化成零和一,因为不知道用double会不会有问题
img=img';%转置
img=flipud(img);%上下颠倒
img=img(:,1:biWidth);%由于在宽度有4个像素要求的补位,所以在这里删除多余
imshow(img);%展示图片
imwrite(img,'p1.bmp');%存储图片
number=zeros(1,256);%开始做直方图,由于1bit只有黑和白比较特殊
for i=1:biHeight
for j=1:biWidth
for index=0:1
if img(i,j)==index
number(1,index*255+1)=number(1,index*255+1)+1;%这里把黑和白从0和1转换过来
end
end
end
end
figure
bar([0:255],number);%作图
end
input('下面我们进行4位bmp的操作,请按回车')%防止图像直接关闭并展示接下来的内容
close all
读取的图片 存储的图片
显示的图片 直方图
程序说明:和1bit的图片相比,4bit的图片在读取表头信息时需要读取一个16*4的调色板,其中16*3分别代表RGB中的一种颜色,剩余列位保留列,一般输出为0。而后以4bit为单位进行像素数据的读取再对应到调色板可以得到各个像素RGB值,构建三维矩阵,在使用ceil将4位字节的宽度对齐后可以得到图像,显示和存储同样使用imshow和imwrite,在直方图的构造时用rgb2gray进行灰度的转化再使用傻瓜查重法进行累计,画出直方图。
bmp=fopen('4.bmp');%打开图后操作与上面一致,先读入表头信息
type=fread(bmp,2,'char');
bmpsize=fread(bmp,1,'long');
bfReserved1and2=fread(bmp,1,'long');
bfOffBits=(fread(bmp,1,'long'));
biSize=fread(bmp,1,'long');
biWidth=fread(bmp,1,'long');
biHeight=fread(bmp,1,'long');
biPlanes=fread(bmp,1,'short');
biBitCount=fread(bmp,1,'short');
biCompression=fread(bmp,1,'long');
biSizeImage=fread(bmp,1,'long');
biXPelsPerMeter=fread(bmp,1,'long');
biYPelsPerMeter=fread(bmp,1,'long');
biClrUsed=fread(bmp,1,'long');
biClrImportant=fread(bmp,1,'long');
size=16;%4位和8位拥有调色板,下面读入调色板信息,放进rgb矩阵中
rgb=zeros(size,4);
for i=1:size
rgb(i,1)=fread(bmp,1);
rgb(i,2)=fread(bmp,1);
rgb(i,3)=fread(bmp,1);
rgb(i,4)=fread(bmp,1);
end
fclose(bmp);
if biBitCount==4%再次判断这次读的图片是4bit的
bmp=fopen('4.bmp','rb');
img=uint8(zeros(biHeight,(ceil(biWidth/8)*8),3));%把默认的double转换成uint8,并对4像素要求进行修正
for i=1:bfOffBits%把头文件信息部分读完,跳到图片信息
fread(bmp,1);
end
for ni=biHeight:-1:1
for nj=1:(ceil(biWidth/8)*8)
temp=fread(bmp,1,'ubit4=>uint8')+1;%以4bit为单位读入
img(ni,nj,3)=rgb(temp,1);%把信息对应到之前的调色板
img(ni,nj,2)=rgb(temp,2);
img(ni,nj,1)=rgb(temp,3);
end
end
fclose(bmp);
figure;
imshow(img);
imwrite(img,'p4.bmp');
number=zeros(1,256);
gray=rgb2gray(img);%做rgb整体的直方图,分别做也是可以的
for i=1:biHeight
for j=1:biWidth
for index=0:255
if gray(i,j)==index%傻瓜查重
number(1,index+1)=number(1,index+1)+1;
end
end
end
end
figure
bar([0:255],number);
end
input('下面我们进行8位bmp的操作,请按回车')
close all
读取的图片 存储的图片
显示的图片 直方图
程序说明:8位和4位的区别仅仅在于8位的调色板是256*4的,在像素读取时以字节为单位读取即可
bmp=fopen('8.bmp');%依旧是读入
type=fread(bmp,2,'char');
bmpsize=fread(bmp,1,'long');
bfReserved1and2=fread(bmp,1,'long');
bfOffBits=(fread(bmp,1,'long'));
biSize=fread(bmp,1,'long');
biWidth=fread(bmp,1,'long');
biHeight=fread(bmp,1,'long');
biPlanes=fread(bmp,1,'short');
biBitCount=fread(bmp,1,'short');
biCompression=fread(bmp,1,'long');
biSizeImage=fread(bmp,1,'long');
biXPelsPerMeter=fread(bmp,1,'long');
biYPelsPerMeter=fread(bmp,1,'long');
biClrUsed=fread(bmp,1,'long');
biClrImportant=fread(bmp,1,'long');
size=256;%这里调色板是2的8次方的,颜色更丰富了
rgb=zeros(size,4);
for i=1:size
rgb(i,1)=fread(bmp,1);
rgb(i,2)=fread(bmp,1);
rgb(i,3)=fread(bmp,1);
rgb(i,4)=fread(bmp,1);
end
fclose(bmp);
if biBitCount==8%还是判断
bmp=fopen('8.bmp','rb');
img=uint8(zeros(biHeight,biWidth,3));
for i=1:bfOffBits
fread(bmp,1);
end
for ni=biHeight:-1:1
for nj=1:biWidth
temp=fread(bmp,1,'uint8=>uint8')+1;%这里以8bit为单位读入并存储为uint8格式
img(ni,nj,3)=rgb(temp,1);
img(ni,nj,2)=rgb(temp,2);
img(ni,nj,1)=rgb(temp,3);
end
end
fclose(bmp);
figure;
imshow(img);
imwrite(img,'p8.bmp');
number=zeros(1,256);
gray=rgb2gray(img);
for i=1:biHeight
for j=1:biWidth
for index=0:255
if gray(i,j)==index
number(1,index+1)=number(1,index+1)+1;
end
end
end
end
figure
bar([0:255],number);
end
input('下面我们进行16位bmp的操作,请按回车')
close all
读取的图片 存储的图片
显示的图像 直方图
程序说明:16bit的图像就没有调色板了,在读取时读取16bit也就是两个字节再以555的方式分配到RGB,剩余的1bit留空,也有图像是565的形式,这里我们在读取头目录的时候了解了解压方式和读取方式,之后在读取时确认是以555的方式读取再转化为uint8的格式进行存储和显示,之后的操作与之前一致。
bmp=fopen('16.bmp');
type=fread(bmp,2,'char');
bmpsize=fread(bmp,1,'long');
bfReserved1and2=fread(bmp,1,'long');
bfOffBits=(fread(bmp,1,'long'));
biSize=fread(bmp,1,'long');
biWidth=fread(bmp,1,'long');
biHeight=fread(bmp,1,'long');
biPlanes=fread(bmp,1,'short');
biBitCount=fread(bmp,1,'short');
biCompression=fread(bmp,1,'long');
biSizeImage=fread(bmp,1,'long');
biXPelsPerMeter=fread(bmp,1,'long');
biYPelsPerMeter=fread(bmp,1,'long');
biClrUsed=fread(bmp,1,'long');
biClrImportant=fread(bmp,1,'long');
fclose(bmp);
%16位这里就没有调色板啦
if biBitCount==16
bmp=fopen('16.bmp','rb');
img=uint8(zeros(biHeight,biWidth,3));
%经过查阅,16位有555和565的格式,我们实例的图片是555所以做的也是555bit的
for i=1:bfOffBits
fread(bmp,1);
end
for ni=biHeight:-1:1
for nj=1:biWidth%555意思就是5位r,5位g,5位b,
temp=fread(bmp,1,'ubit5=>uint8')+1;%以5bit为单位读入再存为uint8格式
img(ni,nj,3)=temp*8;
temp=fread(bmp,1,'ubit5=>uint8')+1;
img(ni,nj,2)=temp*8;
temp=fread(bmp,1,'ubit5=>uint8')+1;
img(ni,nj,1)=temp*8;
temp=fread(bmp,1,'ubit1=>uint8')+1;
end
end
fclose(bmp);
figure;
imshow(img);
imwrite(img,'p16.bmp');
number=zeros(1,256);
gray=rgb2gray(img);
for i=1:biHeight
for j=1:biWidth
for index=0:255
if gray(i,j)==index
number(1,index+1)=number(1,index+1)+1;
end
end
end
end
figure
bar([0:255],number);
end
input('下面我们进行24位bmp的操作,请按回车')
close all
读取的图片 存储的图片
显示的图片 直方图
程序说明:24bit图像直接读取三字节的RGB信息,对应到RGB矩阵中即可完成接下来的操作
bmp=fopen('24.bmp');
type=fread(bmp,2,'char');
bmpsize=fread(bmp,1,'long');
bfReserved1and2=fread(bmp,1,'long');
bfOffBits=(fread(bmp,1,'long'));
biSize=fread(bmp,1,'long');
biWidth=fread(bmp,1,'long');
biHeight=fread(bmp,1,'long');
biPlanes=fread(bmp,1,'short');
biBitCount=fread(bmp,1,'short');
biCompression=fread(bmp,1,'long');
biSizeImage=fread(bmp,1,'long');
biXPelsPerMeter=fread(bmp,1,'long');
biYPelsPerMeter=fread(bmp,1,'long');
biClrUsed=fread(bmp,1,'long');
biClrImportant=fread(bmp,1,'long');
fclose(bmp);
if biBitCount==24
bmp=fopen('24.bmp','rb');
img=uint8(zeros(biHeight,biWidth,3));
for i=1:bfOffBits
fread(bmp,1);
end
for ni=biHeight:-1:1
for nj=1:biWidth
img(ni,nj,3)=fread(bmp,1);
img(ni,nj,2)=fread(bmp,1);
img(ni,nj,1)=fread(bmp,1);
end
end
fclose(bmp);
figure;
imshow(img);
imwrite(img,'p24.bmp');
number=zeros(1,256);
gray=rgb2gray(img);
for i=1:biHeight
for j=1:biWidth
for index=0:255
if gray(i,j)==index
number(1,index+1)=number(1,index+1)+1;
end
end
end
end
figure
bar([0:255],number);
end
input('由此,1位,4位,8位,16位,24位的图像都操作完毕,请按回车')
close all
Python语言
同样为了显示方便,下面为每一深度图片的操作说明,将所有程序顺序链接就是总程序,并且在其中设置了操作提示符,方便阅读时按下回车后再进行下一深度图片的操作,python的处理思路和MATLAB语言一样,但python在读取到bit即从字节读取到位需要先进行二进制到十进制的转换,再对2的各个次方用除法得到各个位的0或1数值
读取的图片 存储的图片
显示的图片 直方图
程序说明:首先引用相关数字处理和图像存储显示的库,用unpack函数对二进制进行十进制转化读取图片的信息,创建三维列表记录图像像素的RGB值,对于1bit的图像在按字节读取后一字节对应了8个像素的信息,用pow函数进行次方求解得到像素信息,把0对应000,1对应255 255 255,得到RGB列表后转化为uint8格式进行显示和存储,再分别对RGB画出直方图
from struct import unpack#用以对读入进行字节的操作
import cv2#用以存储,显示和直方图的显示
import numpy as np#用以对cv2输出图像的辅助
from matplotlib import pyplot as plt
import math#打开文件
with open('p1.bmp','rb') as bmp:#首先进行的是1位图像的操作,先读取信息头
bmptype=unpack("
读取的图像 存储的图像
显示图像 直方图
程序说明:总体思路和matlab一致,程序上在读取一个字节转化成两个4bit时用两个变量分别存储
with open('4.bmp','rb') as bmp:
bmptype=unpack("
读取的图像 存储的图像
显示的图像 直方图
程序说明:读取256*4的调色板,再按字节操作即可
with open('8.bmp','rb') as bmp:
bmptype=unpack("
读取的图片 存储的图片
显示的图片 直方图
程序说明:在读取16位也就是两个字节为一个像素的RGB时要将两个字节顺序调换,再删去调换后第一个字节的头一个bit,再将剩余的15个bit平均分给RGB
with open('16.bmp','rb') as bmp:
bmptype=unpack("
读取的图片 存储的图片
显示的图片 直方图
程序说明:
with open('24.bmp','rb') as bmp:#打开文件
bmptype=unpack("