数字图像处理第一次作业

这学期修了一门数字图像处理的课程,虽然深度学习已经在CV领域大行其道,但是最基础的图像处理也同样需要掌握,通过这门课程,能够弥补一些图像处理的不足,这门课的作业主要会用一些matlab,python和opencv的东西。

作业一

part1

读取一张color map image,将其转换成true color image,并保存为一张jpg图片。

Algorithm

color-map image本质上就是将一张图片存成两个部分,第一个部分是一个图片大小的矩阵I,第二个部分是一个color map查找表,一般是$m \times 3$,m表示color map的维度,将矩阵I中每个数字在color map中找到,然后将其替换成对应的那一行RGB即可,只是注意color map中是$0 \thicksim 1$的double类型,需要乘上255并将其变成uint8类型。

Implement and Result

将color map image 转换为ture image的代码如下

function [real_img ] = transformTrueimage(img, cmap)
%UNTITLED Summary of this function goes here
%   Detailed explanation goes here
[height, width] = size(img);
real_img = zeros(height, width, 3);
for i = 1:height
    for j = 1:width
        idx = img(i, j) + 1;
        real_color = cmap(idx, :) * 255.0;
        real_img(i, j, :) = real_color;
    end
end
real_img = uint8(real_img);
end

文件在assignment1/hw1/transfromTrueimage.m中,运行/assignment1/hw1/test_true.m能够得到两张图片的对比,第一张为color map image,第二张为true image,最后true iamge保存为hw1_true.jpgtest_true.m的代码如下

clear;
clc;

[cimg, cmap] = imread('./hw1.bmp', 'bmp');
true_img = transformTrueimage(cimg, cmap);
imwrite(true_img, 'hw1_treu.jpg');

figure;
image(cimg);
colormap(cmap);
title('color map image');

figure;
image(true_img);
title('true image');

Discussion

这就是一个简单的重新映射的过程,得到的图片之间不会有什么差别。

part2

设计算法将一张true color image转换成color-map image,并尽可能保留原始颜色信息。color map image的colormap维度为256。

Algorithm

读入一张图片I,图片的size是$m \times n \times 3$,那么将每一个像素点取出来就能够得到一个color map索引表,大小是$m*n \times 3$,一般来说m*n都是远远大于256,所以需要设计一个算法来降低维度。

这里我们想到的算法是聚类算法k-means,一共有$m * n$个数据点,每个数据点都是三维的,我们希望能够将他们分成256类,这样我们就能够将ture image中所有的像素点分到这256类上,而这256类就是我们生成的color map索引表。

对于kmeans算法,假设原始数据点是${x_1, x_2, \cdots, x_n}$,我们希望将他们分成k类,首先我们随机初始化k个中心点$u_1, u_2, \cdots, u_k$,那么实现依赖于不断迭代下面公式(1)和(2)。
$$
c^{(i)} = \mathop{arg min}j || x^{(i)} - u_j|| ^ 2
$$
$$
u_j = \frac{\sum
{i=1}^m 1{c^{(i)}=j} x{(i)}}{\sum_{i=1}m 1{c^{(i)} = j}}
$$
公式(1)是说对于每个数据点,每次都找离其最近的中心点,并将其标记为该类,公式(2)是说使用该类所有点的重心作为这一类新的中心点。

使用kmeans算法得到了color map之后,我们就可以将ture image中每个像素点对应于color map中的一个值,这样就得到了color map image。

Implement and Result

kmeans的算法实现如下

function [ u, c ] = KMeans( x, k )
%Implement of Keans Algorithm for cluster colormap image
%   x is a n-dimentional data, and k means how many centers of the cluster
[m, n] = size(x);
u = zeros(k, n);
% initialize kmeans center using random uniform cutting min to max 
sort_x = sort(x, 1);
min_value = sort_x(1, :);
max_value = sort_x(m, :);
for i = 1 : k
    u(i, :) = min_value + (max_value - min_value) .* rand();
end

c = zeros([m, 1]);
last_error = 0;
% iter two formula to converge
while 1
    total_error = 0;
    % fisrt formula
    for i = 1 : m
        min_dist = sum((x(i, :) - u(1, :)) .^ 2);
        c(i) = 1;
        for j = 1 : k
            temp_dist = sum((x(i, :) - u(j, :)) .^ 2);
            if temp_dist < min_dist
                min_dist = temp_dist;
                c(i) = j;
            end
        end
        total_error = total_error + min_dist;
    end
    if abs(total_error - last_error) < 1
        break
    end
    last_error = total_error;
    % second formula
    for i = 1 : k
        temp_u = zeros([1, n]);
        count = 0;
        for j = 1 : m
            if c(j) == i
                temp_u = temp_u + x(j, :);
                count = count + 1;
            end
        end
        if count == 0
            u(i, :) = min_value + (max_value - min_value) .* rand();
        else
            u(i, :) = temp_u ./ count;
        end
    end
end

使用test_kmeans.m来测试了kmeans算法,随机生成三组随机点,然后使用kmeans将其分成三个聚类。

kmeans_dot.jpg
kmeans_result.jpg

然后得到color map image的实现如下

function [ colormap_img, new_cmap ] = transformColormap( img, colormap_dim )
%UNTITLED3 Summary of this function goes here
%   Detailed explanation goes here

[height, width, channel] = size(img);
cmap = zeros(height * width, 3);
for i = 1 : height
    for j = 1 : width
        cmap((i - 1) * width + j, :) = double(img(i, j, :)) / 255; 
    end
end

[new_cmap, c] = KMeans(cmap, colormap_dim);

colormap_img = zeros([height, width]);
for i = 1 : height
    for j = 1 : width
        colormap_img(i, j) = c((i - 1) * width + j);
    end
end

end

最后使用test_colormap.m来测试true image和color map image,先生成两张图片进行肉眼对比,然后使用第一个作业中的函数将color map image再转换回ture image进行误差对比。

jim.jpg
hw1_colormap.jpg

上面一张是true image,下面一张是color map image。

Discussion

通过肉眼我们发现转换成了color map iamge之后,与true image之间的对比不存在太多的误差,同时我设计了一个误差指标,将两幅图每个像素点进行对比,然后取绝对值求和,再除以像素点的总数,这样可以得到平均每个像素点的偏差,最后得到error大约是1.4,说明每个像素点的偏移是比较小的,这也说明了转换之后信息保留得非常多。

作业二

part1

解释图像直方图均衡化原理,并用程序实现。

Algorithm

对于每张读入的图片,可以统计每一个数值的频率形成直方图,其直方图可能会呈现分布不均匀的情况,这样就使得图片没有太高的对比度,而图像直方图均衡化可以对图片中像素个数多的像素级进行展宽,对像素个数少的灰度级进行压缩,从而扩展了图片原取值范围,提高对比图,使得图片更加清晰。

Implement and Result

图像直方图的实现如下

function h = compute_hist( img )
%compute histogram of an image

[m, n, c] = size(img);
h = zeros([256, c]);
for i = 1 : 256
    h(i, :) = sum(sum(img == (i - 1)));
end
end

均衡化的算法实现如下

function [ h, lut, eq_I] = HistogramEqualization( I )
%HistogramEqualization
%   compute histogram of an image and do histogram equalization
[m, n, c] = size(I);
h = compute_hist(I);
[m_h, n_h] = size(h);
total = sum(h);

% construct lut
lut = zeros([m_h, n_h]);
lut(1, :) = h(1, :) ./ total;
for i = 2 : m_h
    lut(i, :) = lut(i - 1, :) + h(i, :) ./ total;
end
for i = 1 : m_h
    lut(i, :) = round(lut(i, :) .* 255);
end
eq_I = zeros(size(I));
for i = 1 : m
    for j = 1 : n
        for k = 1 : c
            eq_I(i, j, k) = lut(I(i, j, k) + 1, k);
        end
    end
end
eq_I = uint8(eq_I);
end

使用test_eq_hist.m来测试均衡化效果,下面是直方图和均衡化之后的图片。

lena.jpg
origin_image_hist.jpg
hist_eq.jpg
equalization_hist.jpg

Discussion

可以发现均衡化之后的图片,直方图变得更加的均匀,同时图片也有了更高的对比度。

part2

输入图片A与参考图片R,对A做变换得到A',使得其统计直方图尽可能与R的统计直方图接近。

Algorithm

两张图片的直方图不可能完全一样,但是我们可以通过匹配分位数来实现两幅图直方图的匹配,对于输入图片I,对于每个像素点,我们先计算出其积累概率函数,然后在参考图片中寻找与这个积累概率函数最接近的像素点,然后将原图片的像素点替换成这个像素点即可,对于给出的输入图片和参考图片,我们可以构造一个查找表方便计算。

Implement and Result

图片匹配的程序如下

function [ K ] = HistogramMatching( I, target )
%UNTITLED8 Summary of this function goes here
%   Detailed explanation goes here
I_h = compute_hist(I);
total_I = sum(I_h);
target_h = compute_hist(target);
total_target = sum(target_h);
[m, n] = size(I_h);
% define pdf for image I
pdf_h = zeros([m, n]);
pdf_h(1, :) = I_h(1, :) ./ total_I;
for i = 2 : m
    pdf_h(i, :) = pdf_h(i - 1, :) + I_h(i, :) ./ total_I;
end
% define pdf for image target 
pdf_target = zeros([m, n]);
pdf_target(1, :) = target_h(1, :) ./ total_I;
for i = 2 : m
    pdf_target(i, :) = pdf_target(i - 1, :) + target_h(i, :) ./ total_target;
end
%define LUT for image transform with target
LUT = zeros([m, n]);
for i = 1 : 256
    for k = 1 : 3
        temp = pdf_h(i, k);
        for j = 1 : 256
            if pdf_target(j, k) > temp
                LUT(i, k) = j;
                break;
            end
        end
    end
end
% get new image close to target image
K = zeros(size(I));
[r, g, b] = size(K);
for i = 1 : r
    for j = 1 : g
        for c = 1 : b
            K(i, j, c) = LUT(I(i, j, c) + 1, c);
        end
    end
end
K = uint8(K);
end

使用test_match.m来测试匹配效果,输入两张图片,得到他们的直方图表示,然后进行图片匹配,将匹配的新图片直方图显示出来进行比较。下图就是所有的结果。

1.jpg

2.jpg
3.jpg
4.jpg
5.jpg
6.jpg

Discussion

可以发现进行匹配之后,图片的色调有了明显的变化,同时根据直方图我们也能够看出原始图片更向参考图片靠拢。


全部代码在github

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,117评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 66,963评论 1 290
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 107,897评论 0 240
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,805评论 0 203
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,208评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,535评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,797评论 2 311
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,493评论 0 197
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,215评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,477评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,988评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,325评论 2 252
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,971评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,807评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,544评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,455评论 2 266

推荐阅读更多精彩内容