zoukankan      html  css  js  c++  java
  • 基于接缝裁剪的图像压缩 算法导论

          给定一副彩色图像,它由一个mxn的像素数组A[1..m,1..n]构成,每个像素是一个红绿蓝(RGB)亮度的三元组。假定我们希望轻度压缩这幅图像。具体地,我们希望从每一行中删除一个像素,使得图像变窄一个像素。但为了避免影响视觉效果,我们要求相邻两行中删除的像素必须位于同一列或相邻列。也就是说,删除的像素构成从顶端行到底端行的一条“接缝”(seam),相邻像素均在垂直或对角线方向上相邻。

            a.证明:可能的接缝数量是m的指数函数,假定n>1.

            第1行有n种可能选取像素点方式,第2到m行中每行有2-3种(可能选中A[i][j-1],A[i][j],A[i][j+1]. (j=1 or j=n时,是2种可能)),所以总共有至少大于n*2^(m-1).

            b 假定现在对每个像素A[i,j]我们都已计算出一个实型的“破坏度”d[i,j],表示删除像素A[i,j]对图像可视效果的破坏程度。直观地,一个像素的破坏度越低,它与相邻像素的相似度越高。再假定一条接缝的破坏度定义为包含的响度的破坏度之和。设计算法,寻找破坏度最低的接缝。分析算法的时间复杂度。

            求破坏度最低的接缝很简单,c[i,j]记录接缝走到当前像素的最低破坏度。从第一行开始,c[i,j]只有当前像素的破坏度,直接赋值即可;第i行,每个像素的上一个像素来源一共有三个,左上、正上和右上方,每次计算c[i,j]时,需要去三种情况中破坏度最低的情况然后加上当前像素的破坏度,就是接缝走到当前像素的最低破坏度。递推式为c[i][j]=d[i][j]+min{c[i-1][j-1],c[i-1][j],c[i-1][j+1]}。

    参考链接:http://www.ithao123.cn/content-6605545.html

    // 15-8.cpp : 定义控制台应用程序的入口点。
    //
    
    #include "stdafx.h"
    #include<iostream>
    #include<time.h>
    #define ROW 10
    #define COL 10
    #define Left -1
    #define Center 0
    #define Right 1
    #define INF 65536
    using namespace std;
    
    int c[ROW + 1][COL + 2];
    int r[ROW + 1][COL + 1];
    int maxj;
    void carving(int d[][COL + 1])
    {
    	//给第0,1行赋值
    	for (int j = 0; j <= COL; j++)   
    	{ 
    		c[0][j] = 0;
    		r[0][j] = Center;
    		c[1][j] = d[1][j];
    		r[1][j] = Center;
    	}
    
    	//给边界0,COL赋值做哨兵,由此在下面求C[i][j]时不用检查j是否为0或COL;
    	for (int i = 0; i <= ROW; i++)  
    	{
    		c[i][0] = INF;
    		c[i][COL + 1] = INF;
    	}
    
    	//根据递归式求c[i][j],从第二行开始
    	for(int i=2;i<=ROW;i++)       
    		for (int j = 1; j <= COL; j++)
    		{
    			int temp = INF;
    			for (int k = j - 1; k <= j + 1; k++)
    			{
    				if (c[i - 1][k] < temp)
    				{
    					temp = c[i - 1][k];
    					r[i][j] = k - j;
    				}
    			}
    			c[i][j] = temp+d[i][j];
    		}
    
    	//求最后一行最小的值就是最小的裁剪代价
    	int temp = INF;
    	for (int j = 1; j <= COL; j++)    
    		if (c[ROW][j] < temp)
    		{ 
    			temp = c[ROW][j];
    			maxj = j;
    		}
    
    	//打印出c[i][j]
    	cout << "c[i][j]:
    " << "最小的切缝代价为" << temp << endl;  
    	for (int i = 1; i <= ROW; i++) {
    		for (int j = 1; j <= COL; j++)
    			cout << c[i][j] << '	';
    		cout << endl;
    	}
    }
    
    //因为从最后一行回推出路径,因此用递归来打印
    void display(int row,int maxj)
    {
    	switch (r[row][maxj])
    	{
    	   case -1:display(row - 1, maxj - 1); cout << "\" << endl; break;
    	   case 0: display(row - 1, maxj); cout << "||" << endl; break;
    	   case  1:display(row - 1, maxj + 1); cout << "//" << endl; break;
    	}
    }
    
    int main()
    {
    	//用5-15随机数初始化d[i][j];
    	srand((int)time(0));   //产生随机数种子
    	int d[ROW + 1][COL + 1];
    	for (int i = 0; i <= ROW; i++)
    		for (int j = 0; j <= COL; j++)
    			d[i][j] = 5 + rand() % 10;
    	cout << "d[i][j]:
    ";
    	for (int i = 1; i <= ROW; i++) {
    		for (int j = 1; j <= COL; j++)
    			cout << d[i][j] << '	';
    		cout << endl;
    	}
    	cout << "----------------------------------------------------------------------------" << endl;
    
        carving(d);
    	cout << "----------------------------------------------------------------------------" << endl;
    	display(ROW, maxj);
    	while (1);
        return 0;
    
    }
    

      结果如下图所示:

     

  • 相关阅读:
    Deepin 安装成功后开机进入系统黑屏
    Widows 关闭 Defender的方法
    yapi
    spring boot集成minio,最新版
    Minio第一课:走进 Minio
    Docker与IPtables
    解决:required a single bean, but 2 were found:
    Python之Beautiful Soup 4使用实例
    mysql -5.7.31 修改root密码
    mybatis/tk mybatis下实体字段是关键字/保留字,执行报错
  • 原文地址:https://www.cnblogs.com/linear/p/6671141.html
Copyright © 2011-2022 走看看