动态规划之基于接缝裁剪的图像压缩



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

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

第一行有n种可能选取像素点方式,第二到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]对图像可视效果的破坏程度。直观地,一个像素的破坏度越低,它与相邻像素的相似度越高。再假定一条接缝的破坏度定义为包含的响度的破坏度之和。设计算法,寻找破坏度最低的接缝。分析算法的时间复杂度。

思考分析:按照要求需要删除的像素是同一列或相邻列。那么就可能删除A[i-1][j-1],A[i-1][j],A[i-1][j+1]之中的任意一个像素点。所以可得递归式:A[i][j]=d[i][j]+min{A[i-1][j-1],A[i-1][j],A[i-1][j+1]}.

代码如下

#include <iostream>
using namespace std;
#define n 6//自定义数组行
#define m 5//自定义数组列
void OP_SEQUENCE(int **A,int i,int j);//i行j列;
int Min(int **A,int i,int j)
{
	int temp=0;
	if (j==1)
	{
		temp=A[i-1][j]>A[i-1][j+1]?A[i-1][j+1]:A[i-1][j];
	}
	else if (j==m)
	{
		temp=A[i-1][j]>A[i-1][j-1]?A[i-1][j-1]:A[i-1][j];
	}
	else
	{
		if (A[i-1][j]>A[i-1][j-1])
		{
			temp=A[i-1][j-1];
			if (A[i-1][j-1]>A[i-1][j+1])
			{
				temp=A[i-1][j+1];
			}
		}
		else
		{
			temp=A[i-1][j];
			if (A[i-1][j]>A[i-1][j+1])
			{
				temp=A[i-1][j+1];
			}
		}
	}
	return temp;
}
void seam_carving(int **d)
{
	int **A,i;//二维数组A表示破坏度之和。
	A=new int*[n+1];
	for (  i=0;i<=n;i++)
	{
		A[i]=new int[m+1];
	}
	for ( i=1;i<=m;i++)
	{
		A[1][i]=d[1][i];
	}
	for ( i=2;i<=n;i++)
	{
		for (int j=1;j<=m;j++)
		{
			A[i][j]=d[i][j]+Min(A,i,j);//递推式
		}
	}
	int MIN=0x7fffffff,t=0;
	for (i=1;i<=m;i++)
	{
		if(A[n][i]<MIN)
		{
			MIN=A[n][i];
            t=i;
		}
	}
	cout<<"MIN破坏点之和="<<MIN<<endl;
	OP_SEQUENCE(A,n,t);
	for ( i = 0; i <=m;  i++)
	      delete[] A[i];
	delete[] A;                     

}
void OP_SEQUENCE(int **A,int i,int j)//i行j列
{//输出一条接缝
	int T;
    if (i==0)return;
	else
	{
		if (j==n)
		{
			T=A[i][j]>A[i][j-1]?j-1:j;
		}
		else if (j==1)
		{
			T=A[i][j]>A[i][j+1]?j+1:j;
		}
		else
		{
			if (A[i][j]>A[i][j-1])
			{
				T=j-1;
				if (A[i][j-1]>A[i][j+1])
				{
					T=j+1;
				}
			}
			else
			{
				T=j;
				if (A[i][j]>A[i][j+1])
				{
					T=j+1;
				}
			}
		}
	}
	OP_SEQUENCE(A,i-1,T);
	cout<<"第"<<i<<"行"<<"第"<<T<<"列像素点->";
}
void main()
{
  int **d,i;
  d=new int*[n+1];
  for ( i=0;i<=n;i++)
  {
	  d[i]=new int[m+1];
  }
  int dd[n+1][m+1]={{0,0,0,0,0,0},{0,3,2,2,3,3},{0,1,2,1,2,1},{0,3,2,1,3,1},{0,2,1,1,2,2},{0,1,2,2,3,3},{0,2,2,2,1,1}};
  for ( i=0;i<=n;i++)
  {
	  for (int j=0;j<=m;j++)
	  {
		  d[i][j]=dd[i][j];
	  }
  }
  seam_carving(d);
}

样例输出

总结:计算上一层最小破坏度时,min函数时间为O(1).计算最小破坏度之和时,seam_carving函数需要O(mn)时间,输出一条接缝时,OP_SEQUENCE函数需要O(n)。总时间为O(mn),这个问题是第三版的新增题,递推式比较简单,程序并不复杂,还是比较容易实现的。

动态规划之基于接缝裁剪的图像压缩

时间: 2024-10-18 22:07:36

动态规划之基于接缝裁剪的图像压缩的相关文章

基于接缝裁剪的图像压缩 算法导论

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

基于预测方法的高光谱图像压缩研究现状

Memon提出预测树的概念,同时利用前向自适应技术与后向自适应技术去除多光谱图像的谱间相关性. []mon N D,Sayood K,Magliveras S S.Lossless Compression of Multispectral Image Data[J].IEEE Transactions on Geoscience and Remote Sensing,1994,32(2):282-289. 张荣等人在预测树的概念上提出了一种侧邻域最小绝对权值预测树构造方法,极大地简化了预测树的构

基于cropper图片裁剪,兼容PC端与移动端

所需的资源文件 <link rel="stylesheet" href="https://cdn.bootcss.com/cropper/4.0.0-beta/cropper.css"> <script src="http://www.jq22.com/jquery/jquery-1.10.2.js"></script> <script src="https://cdn.bootcss.com/

算法导论第十五章动态规划

概述: 1.动态规划是通过组合子问题的解而解决原问题的. 2.动态规划适用于子问题不是独立的情况,也就是各子问题的包含公共的子子问题. 3.动态规划对每个子问题只求解一次,将其结果保存在一张表中. 4.动态规划的设计步骤:a.描述最优解的结构b.递归定义最优解的值c.按自底向上的方式计算最优觖的值d.由计算出的结构构造一个最优解 15.1钢条切割 钢条切割问题:给定定长的钢条和价格表,求切割方案,使得收益最大.如果n英寸的钢条的价格足够大,则不需要切割. 代码如下: //朴素递归求解钢条切割收益

cropbox

今天给大家分享一款基于jQuery头像裁剪插件cropbox,这是一款简单实用的jQuery头像在线裁剪插件.该插件适用于适用浏览器:IE8.360.FireFox.Chrome.Safari.Opera.傲游.搜狗.世界之窗.效果图如下: 在线预览   源码下载 实现的代码. html代码: <div class="container"> <div class="imageBox"> <div class="thumbBox

Android和Linux应用综合对比分析

公开发布的序言: 这篇文章是作于2012年7月12日,也就是自己刚从大学校园迈向工作岗位的时候遇到的第一个题目"请你针对我们公司目前的应用行业场景做一下调研:在终端做应用程序开发的平台是选择Linux好还是Android好"而写的. 在踏出校园之前,自己从来没有接触过安卓的开发领域(除了在2010年下半年买了一部分安卓的智能手机外).接到这个题目后,自己也没有退缩,硬着头皮接下来了,然后凭借自己在学校时候学的一点检索信息写学术论文的小功底,三天之内写下了这篇长达1万4千多字的调研报告,

[Leetcode] word break 拆分词语

Given a string s and a dictionary of words dict, determine if s can be segmented into a space-separated sequence of one or more dictionary words. For example, givens ="leetcode",dict =["leet", "code"]. Return true because&quo

(转)android项目用到的公共类方法

/*** 直接下载图片并加载至控件(非异步加载)* * @param activity* @param urlpath*            图片下载路径* @param imageView*            目标控件* @param isStretch*            是否拉伸图片* @param screenWidth*            屏幕宽度* @return*/public static String loadImageFromNetURL(Activity ac

常见图片、音频、视频格式总结

常见图片.音频.视频格式总结 常见图片音频视频格式总结 常见图片格式总结 图片的有损压缩和无损压缩 PSD格式 JPGJPEG 格式 GIF 格式 BMP 格式 PNG 格式 SWF 格式 CDR 格式 AI 格式 TIFF 格式 SVG格式 EPS格式 DXF格式 TGA格式 HDRI格式 RAW格式 EXIF格式 FPX格式 TGA格式 ICO格式图标 PCX格式 常见音频格式总结 1MP3格式 2WMA格式 3WAV格式 4ASF格式 5AAC格式 6Mp3Pro格式 7VQF格式 8FL