图像裁剪 让我们使用选择行和列范围的方法从图像中提取更大的部分。这也称为裁剪图像。 让我们这次使用不同的图片。让我们看看它的样子。
>> img = imread('bicyle.png');
>> imshow(img);
Ok,那里有经典的两轮车。 我们先来检查一下图像的大小。 >> disp(size(img));好的,320*500。 裁剪此图像时,我们希望我们的限制在此范围内。 假设我们想要选择行110到310以及列10到160。
>> cropped = img(110:310, 10:160);
>> imshow(cropped);
那是前轮。没有意义。 那么裁剪图像的大小是多少? 和以前一样,让我们使用size函数。 >> disp(size(cropped));好的,201*151。 但这那令人惊讶吗?为什么不是200×150呢? 我们回顾一下从310到160的范围。注意,在这两个范围内,限制都是包括在内的。 这就是为什么第一个范围,从110到310,包含201个不同的行。同样,10到160包含151个不同的列。 尝试提取图像的不同部分。当您选择的范围超出范围时会发生什么。我们尝试运行如下代码: >> corrped=img(20:400,10:32)提示执行异常,因为x轴超过了限制范围。 颜色通道我们看一下彩色图像怎么样?让我们来看看:
>> img = imread('fruit.png');
>> imshow(img);
您认为这张图片的大小是多少? >> disp(size(img));结果显示:258 320 3 为什么有三个数字? 前两个是高度和宽度。 第三个是图像中的多个颜色平面或通道,即三个。 那么你如何选择一个颜色的平面呢?我们将使用我们用于裁剪图像的相同索引表示法。 假设我们要选择红色通道,它位于索引1。我们想要所有行,所有列,但只需要第一个平面。 >> img_red = img(:, :, 2);代码运行结果: 这就是红色通道的样子。较亮的区域表示红色值较高,较暗的区域则相反。苹果并不像你期望的那么明亮。 我们看看这个图片的大小: >> disp(size(img_red));代码运行结果:258 320 正如所料,颜色通道的宽度和高度与原始图像相同,但它没有第三个尺寸。 嗯,这是有道理的,不是吗?该颜色平面是三个中的一个,它们堆叠在一起以创建彩色图像。 它们中的每一个都是二维阵列。请注意,提取的颜色通道本身就是一个图像,因此您可以应用之前看到的相同操作。 让我们尝试绘制图像中一行的值。 >> plot(img_red(150, 0));运行代码结果: 这就是图的样子。 在代码编辑器中使用此图像,尝试不同的操作,尝试选择其他彩色通道。 图像相加那么对图像的算术运算是什么样的呢?让我们从添加两个图像开始。 像以前一样,我们加载图像。
>> dolphin = imread('dolphin.png');
>> dolphin = imread('bicycle.png');
运行代码结果: 还要显示它们并确保它们的尺寸相等。
>> imshow(dolphin);
>> disp("Dolphin image size:");
>> disp(size(dolphin));
>> imshow(bicycle);
>> disp("bicycle image size:");
>> disp(size(bicycle));
运行代码结果: 正如我们在程序输出看到的那样, 它们大小相等。这很重要,因为添加的是元素操作的元素。 这意味着一个图像中的像素与相应的像素相加称为另外一个图像。 由于两个图像大小相同,我们可以添加它们。
>> dolphin = imread('dolphin.png');
>> bicycle = imread('bicycle.png');
>> summed = dolphin + bicycle;
>> imshow(summed)
Octave足够智能,可以发现这两个是矩阵相同的大小,因此执行元素添加。运行结果是: 正如你所料,一个包含两个源图像元素的图像。你可以清楚地看到自动车和白色冲浪。你还可以隐约看到海豚。 注意这个图像是非常明亮的。导致许多区域看不到了。 为什么图像会这么的明亮呢? 为了找到答案,让我们回顾一下我们的代码。 请注意,我们直接从两个图像中添加值。两个图像都很明亮的区域变得更加明亮。 这表明我们应该缩小图像强度值。但是要调整多少呢? 我们会想到一个像素,这两个图像都具有最大强度值。求和图像中的像素将具有最大值的两倍。 因此,如果我们想要求和图像中的最大可能值,与每个源图像中的最大可能值相同,那么我们想把强度除以2。
>> dolphin = imread('dolphin.png');
>> bicycle = imread('bicycle.png');
>> average = dolphin / 2 + bicycle / 2;
>> imshow(average);
这看起来熟悉吗?是的,这是两张图片的平均值。让我们看看这是什么样的: Ok,好多了。将此与直接总和相比较: 你可以清楚地看到亮度的差异。另外注意,不再有任何褪色区域。让我们重写平均值的表达式,看看会发生什么。 我们先将两个源图像相加,再去除以2:
>> dolphin = imread('dolphin.png');
>> bicycle = imread('bicycle');
>> average = dolphin / 2 + bicycle / 2;
>> imshow(average);
>> average_alt = (dolphin + bicycle) / 2;
>> imshow(average_alt);
让我们看看运行后的结果: 嗯?这不对呀!这两个结果怎么不一样呢?? 解决这个问题的关键是知道这两个图像都是Uint8类型。 这意味着所有像素值都是0到255范围内的整数。 由于图像是无符号整数,Octave尝试在整个算术运算中保留相同的数据类型。 所以183除以2出来是92。请注意,Octave舍入到最接近的整数。它正在四舍五入 同样地,152除以2是76,它们的总和是168。 在第二种情况下,首先执行添加,因此183加152是335。 但请注意,此数字不适合无符号整数8位范围。 Uint8最大值为255。所以这个数字被截断到上限。除法按预期进行,结果为128。 您可以想象,在许多地方,像素值总计超过255。在所有这些位置,结果只会得到128。这通常小于两个数字的实际平均值。 因此,我们看到第一种方法更好地保留了像素值。 你肯定会遇到这些奇怪的算术错误。请注意您使用的图像数据类型以及执行算术运算的顺序。
|