千图成像

原理:

​ 将原图片切成一个一个的小块,用一个图库比对和这张照片的某一块最相似的图片然后替换掉。

以颜色为基准,找颜色。

三种算法:HSV RGB 直方图

RGB

matlab入门写的最丑的代码。仅以此代码祭奠我!

不过这代码清晰的说明了处理的过程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
init_path='E:\University\Digital image\3999.jpg';
A=imread(init_path);
initp=imresize(A,[600,600]);
imshow(initp);
%imshow(initp);
%imtool(initP);
out_path='E:\University\Digital image\re2.jpg';
init_all='E:\python\WorkSpace\Image\image\';
img_path_list=dir(strcat(init_all,'*.jpg'));
img_num=length(img_path_list);
%imgtest = imread(strcat(init_all, img_path_list(15).name));
%zoom_M=zeros(10,10,3,img_num);

[X,Y,~]=size(initp);
%50*50
X=X/10;
Y=Y/10;
dstImg=zeros(X,Y,3);
for x=0:X-2
for y=0:Y-2
ref_R = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,1);
ref_G = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,2);
ref_B = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,3);
% disp(ref_R);
im_R=0;
im_G=0;
im_B=0;
for i=1:10
for j=1:10
%uint8的范围是0-255
im_R =( im_R+ double(ref_R(i,j)));
im_G =( im_G+ double(ref_G(i,j)));
im_B =( im_B+ double(ref_B(i,j)));
end
end
im_R=im_R/100;
im_G=im_G/100;
im_B=im_B/100;
ImgRGBmax=255;
for t=1:img_num-1
%Imgtest=imread('E:\python\WorkSpace\Image\image\12_1.jpg');
Img1=imread(strcat(init_all,img_path_list(t).name));
Img=imresize(Img1,[10,10]);
%disp(t)
%imshow(Img);
%Img=zoom_M(:,:,:,t);
% fprintf('%d %s\n',t,strcat(init_all,img_path_list(t).name));
Img_R = Img(:,:,1);
Img_G = Img(:,:,2);
Img_B = Img(:,:,3);
img_R=0;
img_G=0;
img_B=0;
for i=1:10
for j=1:10
%uint8的范围是0-255
img_R =( img_R+ double(Img_R(i,j)));
img_G =( img_G+ double(Img_G(i,j)));
img_B =( img_B+ double(Img_B(i,j)));
end
end
img_R=img_R/100;
img_G=img_G/100;
img_B=img_B/100;
dr = abs(im_R-img_R);
dg = abs(im_G-img_G);
db = abs(im_B-img_B);
dsum = (dr+dg+db)/3;
% fprintf('%d \n',dsum);
if(dsum<ImgRGBmax)
ImgRGBmax=dsum;
tx=t;
end
end
fprintf('%d %d %s\n',ImgRGBmax,tx,strcat(init_all,img_path_list(tx).name));
re_img1=imread(strcat(init_all,img_path_list(tx).name));
re_img = imresize(re_img1,[10,10]);
%imshow(re_img);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,1)=re_img(:,:,1);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,2)=re_img(:,:,2);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,3)=re_img(:,:,3);
end
end
imwrite(dstImg,out_path);

效果图:没有,因为这傻逼代码复杂度。。。

先爬去图片将爬取的图片处理成10*10的小图片。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
src_path='E:\python\WorkSpace\Image\image\';
dst_path='E:\python\WorkSpace\Image\simage\';
img_list=dir(strcat(src_path,'*.jpg'));
len=length(img_list);
a = 0;
out = 0;
disp(['There are ', num2str(len), ' images in total.'])
for i = 1:len
i_image = strcat(src_path, img_list(i).name);
try
I = imread(i_image);
catch
disp([i_image, ' processing failed.'])
a = a + 1;
continue
end
[X, Y, ~] = size(I);
I = imresize(I, [10, 10]);
[x, y, ~] = size(I);
if(x~=10 || y~=10)
disp([num2str(x), ', ', num2str(y), ' ¡ª¡ª', img_list(i).name])
out = out + 1;
end
try
imwrite(I, strcat(dst_path, [num2str(i), '.jpg']));
catch
disp([i_image, ' image failed in writing.'])
end
end
disp([num2str(a), ' images failed in reading.']);

千图成像:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
init_path='E:\University\Digital image\3999.jpg';
A=imread(init_path);
initp=A;
imshow(initp);
%imshow(initp);
%imtool(initP);
out_path='E:\University\Digital image\reRGB6.jpg';
init_all='E:\python\WorkSpace\Image\simage\';
img_path_list=dir(strcat(init_all,'*.jpg'));
img_num=length(img_path_list);
%imgtest = imread(strcat(init_all, img_path_list(15).name));
zoom_M=zeros(10,10,3,img_num);
img_R = zeros(500);
img_G = zeros(500);
img_B = zeros(500);
num=1;
%预处理 先算出所有图像的RGB,并分别存入数组中。
for t=1:total
zoom_M(:,:,:,t)=imread(strcat(init_all,img_path_list(t).name));
r=zoom_M(:,:,1,t);
g=zoom_M(:,:,2,t);
b=zoom_M(:,:,3,t);
for i=1:10
for j=1:10

img_R(t) =( img_R(t)+ double(r(i,j)));
img_G(t) =( img_G(t)+ double(g(i,j)));
img_B(t) =( img_B(t)+ double(b(i,j)));
end
end
img_R(t)=img_R(t)/100;
img_G(t)=img_G(t)/100;
img_B(t)=img_B(t)/100;

end

%dstImg_M = initp;
[X, Y, ~] = size(initp);
X=X/10;
Y=Y/10;
for x=0:X-2
for y=0:Y-2
ref_R = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,1);
ref_G = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,2);
ref_B = initp(x*10+1:(x+1)*10,y*10+1:(y+1)*10,3);
% disp(ref_R);
im_R=0;
im_G=0;
im_B=0;
for i=1:10
for j=1:10

im_R =( im_R+ double(ref_R(i,j)));
im_G =( im_G+ double(ref_G(i,j)));
im_B =( im_B+ double(ref_B(i,j)));
end
end
im_R=im_R/100;
im_G=im_G/100;
im_B=im_B/100;
ImgRGBmax=255;

for t=1:img_num-1

dr = abs(im_R-img_R(t));
dg = abs(im_G-img_G(t));
db = abs(im_B-img_B(t));
dsum = (dr+dg+db)/3;
% fprintf('%d \n',dsum);
if(dsum<ImgRGBmax)
ImgRGBmax=dsum;
tx=t;
end
end

fprintf('%d %d %d %s\n',num,ImgRGBmax,tx,strcat(init_all,img_path_list(tx).name));
num=num+1;

re_img=imread(strcat(init_all,img_path_list(tx).name));
%re_img = imresize(re_img1,[10,10]);
%imshow(re_img);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,1)=re_img(:,:,1);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,2)=re_img(:,:,2);
dstImg(x*10+1:(x+1)*10,y*10+1:(y+1)*10,3)=re_img(:,:,3);
end
end
imwrite(dstImg,out_path);

效果图:

原图:

结果:

颜色分布直方图算法:

参考:https://blog.csdn.net/u011600592/article/details/73224512

https://blog.csdn.net/taoyanqi8932/article/details/52758376

http://blog.sina.com.cn/s/blog_4a540be60100vjae.html

直方图介绍

强度直方图图形化显示不同的像素值在不同的强度值上的出现频率,对于灰度图像来说强度

范围为[0~255]之间,对于RGB的彩色图像可以独立显示三种颜色的强度直方图。强度直方

图是用来寻找灰度图像二值化阈值常用而且是有效的手段之一,如果一幅灰度图像的直方图

显示为两个波峰,则二值化阈值应该是这两个波峰之间的某个灰度值。同时强度直方图是调

整图像对比度的重要依据

直方图实现方法:

对一幅灰度图像从上到下,从左到右扫描每个像素值,在每个灰度值上计算像素数目,以这

些数据为基础完成图像直方图的绘制

直方图的性质

直方图反映了图像中的灰度分布规律。它描述每个灰度级具有的像元个数,但不包含这些像元在图像中的位置信息。
任何一幅特定的图像都有唯一的直方图与之对应,但不同的图像可以有相同的直方图。

如果一幅图像有两个不相连的区域组成,并且每个区域的直方图已知,则整幅图像的直方图是该两个区域的直方图之和

基于直方图距离的图像相似度计算:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
%计算图像直方图距离
%巴氏系数计算法

M=imread('1.jpg');
N=imread('2.jpg');
I=rgb2gray(M);
J=rgb2gray(N);

[Count1,x]=imhist(I);
[Count2,x]=imhist(J);
Sum1=sum(Count1);Sum2=sum(Count2);
Sumup = sqrt(Count1.*Count2);
SumDown = sqrt(Sum1*Sum2);
Sumup = sum(Sumup);
figure(1);
subplot(2,2,1);imshow(I);
subplot(2,2,2);imshow(J);
subplot(2,2,3);imhist(I);
subplot(2,2,4);imhist(J);
HistDist=1-sqrt(1-Sumup/SumDown)

弊端分析:

(参考:http://blog.sina.com.cn/s/blog_4a540be60100vjae.html)

(1)直方图匹配。

​ 比如有图像A和图像B,分别计算两幅图像的直方图,HistA,HistB,然后计算两个直方图的归一化相关系数(巴氏距离,直方图相交距离)等等。

​ 这种思想是基于简单的数学上的向量之间的差异来进行图像相似程度的度量,这种方法是目前用的比较多的一种方法,第一,直方图能够很好的归一化,比如通常的256个bin条的。那么两幅分辨率不同的图像可以直接通过计算直方图来计算相似度很方便。而且计算量比较小。

​ 这种方法的缺点:

​ 1、直方图反映的是图像像素灰度值的概率分布,比如灰度值为200的像素有多少个,但是对于这些像素原来的位置在直方图中并没有体现,所以图像的骨架,也就是图像内部到底存在什么样的物体,形状是什么,每一块的灰度分布式什么样的这些在直方图信息中是被省略掉得。那么造成的一个问题就是,比如一个上黑下白的图像和上白下黑的图像其直方图分布是一模一样的,其相似度为100%。

​ 2、两幅图像之间的距离度量,采用的是巴氏距离或者归一化相关系数,这种用分析数学向量的方法去分析图像本身就是一个很不好的办法。

​ 3、就信息量的道理来说,采用一个数值来判断两幅图像的相似程度本身就是一个信息压缩的过程,那么两个256个元素的向量(假定直方图有256个bin条)的距离用一个数值表示那么肯定就会存在不准确性。

Code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
%直方图  来自 crc的代码
ref_path = 'E:\University\Digital image\3999.jpg';
% image to be refered
refM = imread(ref_path);
% image to be created
dstImgName = 'E:\University\Digital image\re4.jpg';
% zoomed image file set folder(10x10)
folder = 'E:\python\WorkSpace\Image\simage\';
img_list = dir(strcat(folder, '*.jpg'));
total = length(img_list);
zoom_M = zeros(10, 10, 3, total);

for i = 1:total
zoom_M(:, :, :, i) = imread(strcat(folder, img_list(i).name));
end

dstImg_M = refM;

[X, Y, ~] = size(refM);
X = X / 10;
Y = Y / 10;

for x = 1:X
for y = 1:Y

sim_cof = 0.0;
tx = 1;
for t = 1:total
img_RGB = zoom_M(:, :, :, t);
sim_sum = 0;
for spec = 1:3
r_g_b = img_RGB(:, :, spec);
r_g_b = reshape(r_g_b, [1, 100]);
ref_r_g_b = refM((x-1)*10+1:x*10, (y-1)*10+1:y*10, spec);
ref_r_g_b = reshape(ref_r_g_b, [1, 100]);

[count1, ~] = hist(r_g_b);
[count2, ~] = hist(double(ref_r_g_b));
sum1 = sum(count1);
sum2 = sum(count2);
sumUp = sqrt(count1.*count2);
sumDown = sqrt(sum1*sum2);
sumUp = sum(sumUp);
hist_cof = 1 - sqrt(1 - sumUp / sumDown);
sim_sum = sim_sum + hist_cof;

end

if(sim_cof < sim_sum)
sim_cof = sim_sum;
tx = t;
end
end

dstImg_M((x-1)*10+1:x*10, (y-1)*10+1:y*10, :) = zoom_M(:, :, :, tx);
fprintf('block (%d, %d) located by image %s. histDist: %f\n', x, y, img_list(tx).name, sim_cof);
end
end

imwrite(dstImg_M, dstImgName);

效果图: