SeamCarver 普林斯顿 算法第四版
算法第四版
文章目录
- 算法第四版
- 引言
- 一、SeamCarver.java
- 1、解析
- 2、代码
- 总结
引言
作业要求链接:
https://coursera.cs.princeton.edu/algs4/assignments/seam/specification.php
作业常见问题解答(包含API的推荐实现顺序):
https://coursera.cs.princeton.edu/algs4/assignments/seam/faq.php
本次作业需要完成一个名为SeamCarver的内容感知的图像大小调整技术。通过该技术,可以在保留图像感兴趣特征的前提下实现裁剪和缩放。
如下图,上方是原始的505×287像素的图像;下方是移除150条垂直接缝后的结果,从而使图像缩小30%。
一、SeamCarver.java
1、解析
计算energy的部分较为简单,主要讨论如何找最小路径。
lab中推荐使用拓扑排序或动态规划来找最小路径,这里仅讨论拓扑排序。
在此,最小路径的主要思路就是首先进行拓扑排序,然后对每个点relax(松弛)。
(1)拓扑排序实际上拓扑排序实际上就是有优先级限制的排序,可以理解为我必须先在第i行找一点,那么才能在i+1行再找一点。因此我们一行一行遍历,也就实现了拓扑排序。
(2)relax,对于点(x,y),我们需要对(x-1,y+1),(x,y+1),(x+1,y+1)这三个相邻点进行判断,并改变disto和pathto。
细节部分
(1)见specific,中如何优化代码,主要考虑代码复用问题
(2)使用矩阵转置tranpose,,即水平和竖直,只要完成其中一个,另一个可通过转置图片,能量图来实现。
public class SeamCarver {// create a seam carver object based on the given picturepublic SeamCarver(Picture picture)// current picturepublic Picture picture()// width of current picturepublic int width()// height of current picturepublic int height()// energy of pixel at column x and row ypublic double energy(int x, int y)// sequence of indices for horizontal seampublic int[] findHorizontalSeam()// sequence of indices for vertical seampublic int[] findVerticalSeam()// remove horizontal seam from current picturepublic void removeHorizontalSeam(int[] seam)// remove vertical seam from current picturepublic void removeVerticalSeam(int[] seam)// unit testing (optional)public static void main(String[] args)}
2、代码
import edu.princeton.cs.algs4.Picture;public class SeamCarver {private Picture picture;private double[][] energy;// create a seam carver object based on the given picturepublic SeamCarver(Picture picture) {if (picture == null) {throw new IllegalArgumentException();}this.picture = picture;computeenergy();}// current picturepublic Picture picture() {return this.picture;}// width of current picturepublic int width() {return picture.width();}// height of current picturepublic int height() {return picture.height();}private void computeenergy() {double[][] energy = new double[width()][height()];for (int i = 0; i < width(); i++) {for (int j = 0; j < height(); j++) {energy[i][j] = energy(i, j);}}this.energy = energy;}// energy of pixel at column x and row ypublic double energy(int x, int y) {if (!(x >= 0 && x <= width() - 1)) {throw new IllegalArgumentException();}if (!(y >= 0 && y <= height() - 1)) {throw new IllegalArgumentException();}if (x == 0 || x == width() - 1 || y == 0 || y == height() - 1) {return 1000;} else {// x-gradientint left = this.picture.getRGB(x - 1, y);int right = this.picture.getRGB(x + 1, y);int R_x = ((left >> 16) & 0xFF) - ((right >> 16) & 0xFF);int G_x = ((left >> 8) & 0xFF) - ((right >> 8) & 0xFF);int B_x = ((left) & 0xFF) - ((right) & 0xFF);int RGB_x = R_x * R_x + G_x * G_x + B_x * B_x;// Y-gradientint top = this.picture.getRGB(x, y + 1);int bottom = this.picture.getRGB(x, y - 1);int R_y = ((top >> 16) & 0xFF) - ((bottom >> 16) & 0xFF);int G_y = ((top >> 8) & 0xFF) - ((bottom >> 8) & 0xFF);int B_y = ((top) & 0xFF) - ((bottom) & 0xFF);int RGB_y = R_y * R_y + G_y * G_y + B_y * B_y;return Math.sqrt(RGB_x + RGB_y);}}// sequence of indices for horizontal seampublic int[] findVerticalSeam() {double disto[][] = new double[width()][height()];int pathto[][] = new int[width()][height()];for (int col = 0; col < width(); col++) {for (int row = 0; row < height(); row++) {if (row == 0) disto[col][row] = energy[col][row];else disto[col][row] = Double.MAX_VALUE;}}for (int row = 0; row < height() - 1; row++) {for (int col = 0; col < width(); col++) {relax(col - 1, row + 1, col, row, disto, pathto);relax(col, row + 1, col, row, disto, pathto);relax(col + 1, row + 1, col, row, disto, pathto);}}// find min mindistoint min_disto = -1;double min_energy = Double.MAX_VALUE;for (int col = 0; col < width(); col++) {if (disto[col][height() - 1] < min_energy) {min_energy = disto[col][height() - 1];min_disto = col;}}// find the pathint[] rs = new int[height()];for (int i = height() - 1; i >= 0; i--) {rs[i] = min_disto;min_disto = pathto[min_disto][i];}return rs;}// sequence of indices for Horizontal seampublic int[] findHorizontalSeam() {trans(this.picture);int[] res;res = findVerticalSeam();trans(this.picture);return res;}private void trans(Picture picture) {int newheight = width();int newwidth = height();Picture newpicture = new Picture(newwidth, newheight);for (int i = 0; i < newheight; i++) {for (int j = 0; j < newwidth; j++) {newpicture.setRGB(j, i, picture.getRGB(i, j));}}this.picture = newpicture;computeenergy();newpicture = null;}private void relax(int col, int row, int lastcol, int lastrow, double disto[][], int pathto[][]) {if ((col >= 0 && col <= width() - 1 && row >= 0 && row <= height() - 1)) {// out_of_bounddouble w = energy[col][row];// double a = disto[col][row];if (disto[col][row] > disto[lastcol][lastrow] + w) {//double b = disto[lastcol][row - 1] + w;disto[col][row] = disto[lastcol][lastrow] + w;pathto[col][row] = lastcol;}}}// remove vertical seam from current picturepublic void removeVerticalSeam(int[] seam) {if (seam == null) {throw new IllegalArgumentException();}if (seam.length != height()) {throw new IllegalArgumentException();}if (width() <= 1) {throw new IllegalArgumentException();}for (int k : seam) {if (!(k >= 0 && k <= width() - 1)) {throw new IllegalArgumentException();}}Picture newpicture = new Picture(width() - 1, height());for (int j = 0; j < height(); j++) {int ii = 0;for (int i = 0; i < width() - 1; i++) {if (seam[j] == i) {ii++;}newpicture.setRGB(i, j, this.picture.getRGB(ii, j));ii++;}}this.picture = newpicture;computeenergy();newpicture = null;}// remove horizontal seam from current picturepublic void removeHorizontalSeam(int[] seam) {trans(this.picture);removeVerticalSeam(seam);trans(this.picture);}// unit testing (optional)public static void main(String[] args) {}
}
总结
最终得分90/100,只有少部分参考了其他博主,算较为满意的一次lab
SeamCarver 普林斯顿 算法第四版相关推荐
- WordNet 普林斯顿 算法第四版
普林斯顿 算法第四版 本文的代码以及之前的作业代码可通过一下github链接获得 https://github.com/Changjing-Liu/algorithm_lab 文章目录 普林斯顿 算法 ...
- BoggleSolver 普林斯顿 算法第四版
BoggleSolver 普林斯顿 算法第四版 文章目录 BoggleSolver 普林斯顿 算法第四版 一. 引言 1. Boggle 2. 计分 3. Qu特殊情况 4. 任务要求 二.分析 1. ...
- 1.1.10 从二分查找BinarySearch开启算法学习之路---《java算法第四版》
文章目录 0.前言 1.功能 2.示例 有两个名单tinyW.txt和tinyT.txt,将tinyT.txt名单中不在tinyW.txt的数据打印出来 ① 实现原理 ② 实现代码 ③ 性能分析 0. ...
- 0202插入删除-算法第四版红黑树-红黑树-数据结构和算法(Java)
文章目录 4 插入 4.1 序 4.2 向单个2-结点插入新键 4.3 向树底部的2-结点插入新键 4.4 向一棵双键树(3-结点)中插入新键 4.5 颜色调整 4.6 根结点总是黑色 4.7 向树底 ...
- 算法第四版扔鸡蛋问题
本题来源于算法第四版1.4.25.1.4.26. 同时好像记得看过的腾讯面经里也问到过类似题目,因此觉得有必要仔细做一下. 题目如下: 一幢 100 层的大楼,给你两枚鸡蛋.假设,在第 n 层扔下鸡蛋 ...
- 算法第四版- 3.1
算法第四版- 3.1 文章目录 **算法第四版- 3.1** 1.二分查找 1)LC704二分查找 2)LC744二分查找 3)LC33搜索旋转排序数组 4)搜索旋转数组进阶 2.跳表 1.二分查找 ...
- 《算法第四版》官方jar包中In的readStrings()方法不建议使用的解决办法
起因:在学习<算法第四版>过程中总是遇到一些算法之外的小问题,比如本书中所需要下载的库.今天在学习排序那一节时,发现排序框架main()方法中的In的readStrings()方法不能使用 ...
- 算法第四版课后习题答案 西安电子科技大学 计算机学院 算法课
来源于西电计算机15级学长学姐,算法第四版课后习题答案 西安电子科技大学 计算机学院 算法课. 再推荐一个好的看答案的地方,每一题都有,只是还没有更新完成. 地址:https://alg4.ike ...
- Algorithms, 4th Edition(算法-第四版)源码使用系统配置
关于-Algorithms, 4th Edition (算法-第四版)源代码在本地机器的运行配置. 其实关于这个教程的使用已经在 Java Algorithms and Clients 页面中写出,并 ...
最新文章
- 快速android app开发,快速學會開發 Android App
- Python程序设计题解【蓝桥杯官网题库】 DAY4【补】-基础练习
- ORACLE纯SQL实现多行合并一行
- HTML滚动条S默认最小值,css修改滚动条默认样式
- android handler封装_Handler都没搞懂,你拿什么去跳槽啊?!
- cobertura试用
- python isodd()判断奇偶_EXCEL VBA:Iseven Isodd 判断奇偶
- 黑群晖二合一已损毁_黑群晖DSM6.2硬盘引导二合一镜像以及安装方法
- 【JTT1078视频服务器】之音视频的拆解
- NutUI Bingo - 基于 Vue 3.0 的移动端抽奖组件,由京东前端团队打造
- 世人皆苦,唯有自渡的句子,句句触动灵魂!
- 【转载】SOP SO SOIC TSSOP SSOP 封装直观比较图
- V853 替换开机启动LOGO
- 计网复习——传输层习题
- python(第七天)
- 仪表板工具Stimulsoft Dashboards中的面板组件介绍
- 30句2018年精彩走心的文案,没事可以学习下,了解其中的文字意义
- 分享一个破解百度网盘下载速度的工具
- Android开发人员的代码速查字典
- 为什么索引会加快查询速度?索引原理和使用原则