在數字圖像處理領域,圖像壓縮是一個永恒的話題,我們常常需要在保證圖像質量的前提下,盡可能地減小文件大小,以節省存儲空間、加快網絡傳輸速度,除了常見的JPEG、PNG等有損或無損壓縮格式外,從圖像數據本身的位深度入手進行壓縮,是一種簡單而高效的精簡方法,本文將詳細介紹如何利用MATLAB中的bitget函數,通過降低圖像位深度來實現圖像壓縮,并探討其原理、實現步驟與效果。
什么是位深度與圖像壓縮?
在開始之前,我們首先要理解兩個核心概念:

-
位深度:位深度指的是存儲一個像素點顏色所使用的二進制位數,位數越多,能表示的顏色范圍就越廣,圖像色彩層次就越豐富,常見的位深度有:
- 8位:這是最標準的形式,通常指灰度圖像(256個灰度級,0-255)或彩色圖像的每個通道(RGB各有256個級別)。
- 16位:每個通道有65536個級別,能記錄更豐富的色彩和亮度細節,常用于專業攝影和后期制作。
- 24位:通常指真彩色圖像,由8位的紅、綠、藍三個通道疊加而成,總共約1670萬種顏色。
-
圖像壓縮:圖像壓縮的目的是減少表示圖像所需的數據量,它分為兩類:
- 無損壓縮:壓縮后可以完全還原原始圖像,沒有任何信息損失,例如PNG格式。
- 有損壓縮:壓縮過程中會丟棄一部分人眼不敏感的數據,以換取更高的壓縮率,例如JPEG格式。
我們今天要討論的位深度壓縮,本質上是一種有損壓縮,通過減少表示像素的位數,我們直接丟棄了最低位的顏色信息,從而減小了圖像的數據量。
核心工具:bitget函數
MATLAB的bitget函數是實現位深度壓縮的關鍵,它的作用是從一個整數中提取指定位的值。
語法: c = bitget(A, bit)
參數說明:
A:輸入的整數數組(在我們的場景中,就是圖像矩陣)。bit:要提取的位的位置,從1(最低位)到最高位。
返回值:

c:一個與A大小相同的數組,其元素是A中對應元素指定位的值(0或1)。
簡單示例: 假設我們有一個像素值 A = 200(二進制為 11001000)。
bitget(200, 1)提取最低位,得到0。bitget(200, 8)提取最高位,得到1。
bitget函數就像一個精密的“數字鑷子”,能精準地操作圖像數據中的每一位,這正是我們進行位深度壓縮的基礎。
使用bitget進行圖片壓縮的步驟
下面我們通過一個具體的例子,將一幅標準的24位彩色圖(每個通道8位)壓縮到4位,來演示整個流程。
第一步:讀取原始圖像
我們使用imread函數讀取一張圖片,為了清晰展示效果,我們選擇一張色彩豐富的圖片。
% 讀取原始圖像
original_img = imread('peppers.png');
% 假設原始圖像是 uint8 類型,每個通道8位
% 顯示原始圖像
figure;
subplot(1, 2, 1);
imshow(original_img);'原始圖像 (8-bit per channel)');
第二步:確定目標位深度并進行數據截斷
假設我們的目標是將每個顏色通道從8位壓縮到4位,這意味著我們只需要保留原始8位數據中的高4位,而丟棄低4位。

如何實現?我們可以利用bitget提取高4位(即第5位到第8位),然后將它們重新組合成一個4位的整數。
% 目標位深度 target_bits = 4; % 提取高4位 (第5, 6, 7, 8位) % 注意:bit的位置從1開始計數 high_4_bit = bitget(original_img, 8:-1:8-target_bits 1); % 將邏輯數組 (true/false) 轉換為 double (0/1) high_4_bit = double(high_4_bit); % 將4位數據重新組合成一個整數 % [b8, b7, b6, b5] -> b8*8 b7*4 b6*2 b5*1 compressed_img = uint8(high_4_bit(:,:,1) * 2^3 high_4_bit(:,:,2) * 2^2 high_4_bit(:,:,3) * 2^1 high_4_bit(:,:,4) * 2^0);
代碼解釋:
bitget(original_img, 8:-1:8-target_bits 1):一次性提取了每個像素值的高4位。8:-1:5表示從第8位提取到第5位。double(high_4_bit):bitget返回的是邏輯類型(logical),我們需要將其轉換為double類型以便進行后續的數學運算。compressed_img = ...:這一步是核心,我們將提取出的4個位(現在它們是0或1的矩陣)通過加權求和的方式,重新組合成一個0到15之間的整數,如果高4位是1101,計算結果就是1*8 1*4 0*2 1*1 = 13。
第三步:顯示并比較結果
我們將原始圖像和壓縮后的圖像放在一起進行對比。
% 顯示壓縮后的圖像
subplot(1, 2, 2);
imshow(compressed_img);['壓縮圖像 (', num2str(target_bits), '-bit per channel)']);
% 計算壓縮率
original_size = numel(original_img); % 像素總數
compressed_size = numel(compressed_img);
compression_ratio = (1 - compressed_size / original_size) * 100;
fprintf('原始圖像大小: %d 像素\n', original_size);
fprintf('壓縮后圖像大小: %d 像素\n', compressed_size);
fprintf('數據量減少了: %.2f%%\n', compression_ratio);
效果分析: 運行上述代碼,你會發現壓縮后的圖像出現了明顯的色帶或輪廓效應,這是因為從256個級別銳減到16個級別,色彩過渡不再平滑,圖像的主體結構和內容依然可辨,控制臺會輸出壓縮率,對于從8位到4位的壓縮,數據量正好減少了一半(50%)。
更通用的壓縮函數
為了方便重復使用,我們可以將上述邏輯封裝成一個函數。
function compressed_img = compress_image_by_bits(original_img, target_bits)
% COMPRESS_IMAGE_BYBITS 通過降低位深度來壓縮圖像
% compressed_img = compress_image_bybits(original_img, target_bits)
% 將原始圖像的每個通道壓縮到 target_bits 位。
% 檢查輸入有效性
if ~ismember(class(original_img), {'uint8', 'uint16'})
error('輸入圖像必須是 uint8 或 uint16 類型。');
end
if target_bits <= 0 || target_bits >= 16
error('目標位深度應在1到15之間。');
end
% 獲取原始位深度
original_bits = intmax(class(original_img)); % 對于uint8是255, uint16是65535
% 提取目標的高位
bits_to_get = original_bits:-1:original_bits-target_bits 1;
high_bits = bitget(original_img, bits_to_get);
% 轉換并重組
high_bits = double(high_bits);
weights = 2.^(target_bits-1:-1:0);
% 對每個通道進行計算
if size(high_bits, 3) == 1 % 灰度圖
compressed_img = uint8(sum(high_bits .* weights, 3));
else % 彩色圖
compressed_img = uint8(sum(high_bits .* weights, 4));
end
end
使用這個函數非常簡單:
% 使用通用函數進行壓縮 compressed_img_5bit = compress_image_by_bits(original_img, 5); figure; imshow(compressed_img_5bit);['壓縮圖像 (5-bit per channel)']);
總結與展望
利用bitget函數進行位深度壓縮,是MATLAB中一種非常直觀且強大的圖像處理技巧,它的優點在于:
- 實現簡單:核心邏輯清晰,代碼量少。
- 原理明確:直接操作圖像數據的最小單位——位
鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯系我們修改或刪除,多謝。

