{"id":283496,"date":"2017-03-19T16:46:11","date_gmt":"2017-03-19T13:46:11","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=283496"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=283496","title":{"rendered":"\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e"},"content":{"rendered":"<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (Content Aware Image Resize), \u0436\u0438\u0434\u043a\u043e\u0435 \u0440\u0430\u0441\u0442\u044f\u0436\u0435\u043d\u0438\u0435 (liquid resizing), \u0440\u0435\u0442\u0430\u0440\u0433\u0435\u0442\u0438\u043d\u0433 (retargeting) \u0438\u043b\u0438 \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u0438\u0435 \u0448\u0432\u0430 (seam carving) \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c <em>\u0448\u0432\u044b<\/em>, \u0438\u043b\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u0435\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0443\u0442\u0438, \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u0431 \u044d\u0442\u043e\u0439 \u0438\u0434\u0435\u0435 \u044f \u0443\u0437\u043d\u0430\u043b \u0438\u0437 <a href=\"https:\/\/www.youtube.com\/watch?v=qadw0BRKeMk\">\u0440\u043e\u043b\u0438\u043a\u0430 \u043d\u0430 YouTube<\/a>, \u043e\u0442 Shai Avidan \u0438 Ariel Shamir.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0431\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u0434\u0435\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Rust \ud83d\ude42<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u043e\u043f\u044b\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u044f \u043f\u043e\u0438\u0441\u043a\u0430\u043b \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443<sup><a rel=\"footnote\" href=\"#fn:duckduck\">1<\/a><\/sup> <code>&quot;sample image&quot;<\/code>, \u0438 \u043d\u0430\u0448\u0435\u043b \u0435\u0451<sup><a href=\"#myfootnote2\">2<\/a><\/sup>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/63d\/4b1\/dc3\/63d4b1dc37d4495c8aa36c931a30b02b.jpeg\"\/><br \/>  <a name=\"habracut\"><\/a><\/p>\n<h1 id=\"sozdayom-maket-soglasno-nishodyaschemu-podhodu\">\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u043c\u0430\u043a\u0435\u0442 \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u043d\u0438\u0441\u0445\u043e\u0434\u044f\u0449\u0435\u043c\u0443 \u043f\u043e\u0434\u0445\u043e\u0434\u0443<\/h1>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u043c\u043e\u0437\u0433\u043e\u0432\u043e\u0439 \u0448\u0442\u0443\u0440\u043c. \u0414\u0443\u043c\u0430\u044e, \u043d\u0430\u0448\u0430 \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 \u043c\u043e\u0436\u0435\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c\u0441\u044f \u0442\u0430\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/\/ caller.rs let mut image = car::load_image(path); \/\/ \u0417\u0430\u0434\u0430\u0434\u0438\u043c \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0439 \u0440\u0430\u0437\u043c\u0435\u0440? image.resize_to(car::Dimensions::Absolute(800, 580)); \/\/ \u0423\u0434\u0430\u043b\u0438\u043c 20 \u0441\u0442\u0440\u043e\u043a? image.resize_to(car::Dimensions::Relative(0, -20)); \/\/ \u041c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0436\u0435\u043c \u0432 \u043e\u043a\u043d\u0435? car::show_image(&amp;image); \/\/ \u0418\u043b\u0438 \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u043c \u043d\u0430 \u0434\u0438\u0441\u043a\u0435? image.save(&quot;resized.jpeg&quot;);<\/code><\/pre>\n<p>  <\/p>\n<p>\u0421\u0430\u043c\u044b\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0432 <code>lib.rs<\/code> \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0431\u044b\u0442\u044c \u0442\u0430\u043a\u0438\u043c\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">\/\/\/ lib.rs pub fn load_image(path: Path) -&gt; Image {     \/\/ \u0417\u0430\u0431\u0443\u0434\u0435\u043c \u043f\u043e\u043a\u0430 \u043e\u0431 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043e\u0448\u0438\u0431\u043e\u043a :)     Image {         inner: some_image_lib::load(path).unwrap(),     } }  impl Image {     pub fn resize_to(&amp;mut self, dimens: Dimensions) {         \/\/ \u0421\u043a\u043e\u043b\u044c\u043a\u043e \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432 \u0438 \u0441\u0442\u0440\u043e\u043a \u0432\u0441\u0442\u0430\u0432\u0438\u0442\u044c\/\u0443\u0434\u0430\u043b\u0438\u0442\u044c?         let (mut xs, mut ys) = self.size_diffs(dimens);         \/\/ \u041f\u0440\u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u0441\u0442\u0440\u043e\u043a \u0438 \u0441\u0442\u043e\u043b\u0431\u0446\u043e\u0432,         \/\/ \u043c\u044b \u0437\u0430\u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043e\u0432\u0430\u043d\u044b \u0432\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u043f\u0443\u0442\u044c \u0441 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0432\u0435\u0441\u043e\u043c,         \/\/ \u043d\u0435 \u0432\u0430\u0436\u043d\u043e \u0441\u0442\u0440\u043e\u043a\u0430 \u044d\u0442\u043e \u0438\u043b\u0438 \u0441\u0442\u043e\u043b\u0431\u0435\u0446.         while xs != 0 &amp;&amp; ys != 0 {             let best_horizontal = image.best_horizontal_path();             let best_vertical = image.best_vertical_path();             \/\/ \u0412\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u0443\u0442\u044c \u0441 \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u043c \u0441\u0447\u0435\u0442\u043e\u043c.             if best_horizontal.score &lt; best_vertical.score {                 self.handle_path(best_horizontal, &amp;mut xs);             } else {                 self.handle_path(best_vertical, &amp;mut ys);             }         }         \/\/ \u041e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0432 \u043e\u0431\u043e\u0438\u0445 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f\u0445.         while xs != 0 {             let path = image.best_horizontal_path();             self.handle_path(path, &amp;mut xs);         }         while ys != 0 {             let path = image.best_vertical_path();             self.handle_path(path, &amp;mut ys);         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u0434\u0430\u0435\u0442 \u043d\u0430\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043e \u0442\u043e\u043c, \u043a\u0430\u043a \u043f\u043e\u0434\u0445\u043e\u0434\u0438\u0442\u044c \u043a \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044e \u0441\u0438\u0441\u0442\u0435\u043c\u044b. \u041d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u0442\u044c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443, \u043d\u0430\u0439\u0442\u0438 \u044d\u0442\u0438 \u0448\u0432\u044b \u0438\u043b\u0438 \u043f\u0443\u0442\u0438, \u0438 \u043e\u0431\u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0443\u0434\u0430\u043b\u0435\u043d\u0438\u0435 \u0442\u0430\u043a\u043e\u0433\u043e \u043f\u0443\u0442\u0438 \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e, \u043d\u0430\u043c \u0431\u044b \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0443\u0432\u0438\u0434\u0435\u0442\u044c \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043d\u0430\u0447\u0430\u043b\u0430 \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043c \u043d\u0430\u0448\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435. \u041c\u044b \u0443\u0436\u0435 \u0437\u043d\u0430\u0435\u043c \u043a\u0430\u043a\u043e\u0439 API \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c.<\/p>\n<p>  <\/p>\n<h1 id=\"image\">image<\/h1>\n<p>  <\/p>\n<p>\u0411\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0430 <a href=\"https:\/\/crates.io\/crates\/image\"><code>image<\/code><\/a> \u043e\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u043e\u0432 \u201cPiston\u201d \u043a\u0430\u0436\u0435\u0442\u0441\u044f \u043f\u043e\u0434\u043e\u0439\u0434\u0435\u0442, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448 <code>Cargo.toml<\/code> \u0437\u0430\u043f\u0438\u0441\u044c: <code>image = &quot;0.12&quot;<\/code>. \u0411\u044b\u0441\u0442\u0440\u044b\u0439 \u043f\u043e\u0438\u0441\u043a \u0432 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0438 \u044d\u0442\u043e \u0432\u0441\u0435, \u0447\u0442\u043e \u0442\u0440\u0435\u0431\u0443\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">struct Image {     inner: image::DynamicImage, }  impl Image {     pub fn load_image(path: &amp;Path) -&gt; Image {         Image {             inner: image::open(path).unwrap()         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0415\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u0437\u043d\u0430\u0442\u044c \u043a\u0430\u043a \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 \u0438\u0437<br \/>  <code>image::DynamicImage<\/code>. \u041a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440 image \u043d\u0435 \u043c\u043e\u0436\u0435\u0442 \u044d\u0442\u043e\u0433\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c, \u043d\u043e \u0443 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <a href=\"https:\/\/crates.io\/crates\/imageproc\"><code>imageproc<\/code><\/a> \u0435\u0441\u0442\u044c \u0444\u0443\u043d\u043a\u0446\u0438\u044f: <code>imageproc::gradients::sobel_gradients<\/code>. \u041e\u0434\u043d\u0430\u043a\u043e \u043d\u0430\u0441 \u043f\u043e\u0434\u0436\u0438\u0434\u0430\u0435\u0442 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u043f\u0440\u043e\u0431\u043b\u0435\u043c\u0430<sup><a href=\"#myfootnote3\">3<\/a><\/sup>. \u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>sobel_gradient<\/code> \u043f\u0440\u0438\u043d\u0438\u043c\u0430\u0435\u0442 8-\u0431\u0438\u0442\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0433\u0440\u0430\u0434\u0430\u0446\u0438\u044f\u0445 \u0441\u0435\u0440\u043e\u0433\u043e, \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 16-\u0431\u0438\u0442\u043d\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0432 \u0433\u0440\u0430\u0434\u0430\u0446\u0438\u044f\u0445 \u0441\u0435\u0440\u043e\u0433\u043e. \u0418\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0437\u0438\u043b\u0438 \u2014 \u044d\u0442\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 RGB \u0441 8 \u0431\u0438\u0442\u0430\u043c\u0438 \u043d\u0430 \u043a\u0430\u043d\u0430\u043b. \u0422\u0430\u043a \u0447\u0442\u043e \u043f\u0440\u0438\u0434\u0435\u0442\u0441\u044f \u0440\u0430\u0437\u043b\u043e\u0436\u0438\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u044b \u043d\u0430 R, G \u0438 B, \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0432 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u043e\u0442\u0442\u0435\u043d\u043a\u0430\u0445 \u0441\u0435\u0440\u043e\u0433\u043e \u0438 \u0432\u044b\u0447\u0438\u0441\u043b\u0438\u0442\u044c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u043a\u0430\u0436\u0434\u043e\u0433\u043e \u0438\u0437 \u043d\u0438\u0445. \u0410 \u0437\u0430\u0442\u0435\u043c \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u044b \u0432\u043c\u0435\u0441\u0442\u0435 \u0432 \u043e\u0434\u043d\u043e \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435, \u0432 \u043a\u043e\u0442\u043e\u0440\u043e\u043c \u043c\u044b \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u043f\u0443\u0442\u044c.<\/p>\n<p>  <\/p>\n<p>\u042d\u0442\u043e \u044d\u043b\u0435\u0433\u0430\u043d\u0442\u043d\u043e? \u041d\u0435\u0442. \u042d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c? \u0412\u043e\u0437\u043c\u043e\u0436\u043d\u043e \ud83d\ude42<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">type GradientBuffer = image::ImageBuffer&lt;image::Luma&lt;u16&gt;, Vec&lt;u16&gt;&gt;;  impl Image {     pub fn load_image(path: &amp;Path) -&gt; Image {         Image {             inner: image::open(path).unwrap()         }     }      fn gradient_magnitude(&amp;self) -&gt; GradientBuffer {         \/\/ \u041c\u044b \u043f\u0440\u0435\u0434\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c RGB         let (red, green, blue) = decompose(&amp;self.inner);         let r_grad = imageproc::gradients::sobel_gradients(red.as_luma8().unwrap());         let g_grad = imageproc::gradients::sobel_gradients(green.as_luma8().unwrap());         let b_grad = imageproc::gradients::sobel_gradients(blue.as_luma8().unwrap());          let (w, h) = r_grad.dimensions();         let mut container = Vec::with_capacity((w * h) as usize);         for (r, g, b) in izip!(r_grad.pixels(), g_grad.pixels(), b_grad.pixels()) {             container.push(r[0] + g[0] + b[0]);         }         image::ImageBuffer::from_raw(w, h, container).unwrap()     } }  fn decompose(image: &amp;image::DynamicImage) -&gt; (image::DynamicImage,                                               image::DynamicImage,                                               image::DynamicImage) {     let w = image.width();     let h = image.height();     let mut red = image::DynamicImage::new_luma8(w, h);     let mut green = image::DynamicImage::new_luma8(w, h);     let mut blue = image::DynamicImage::new_luma8(w, h);     for (x, y, pixel) in image.pixels() {         let r = pixel[0];         let g = pixel[1];         let b = pixel[2];         red.put_pixel(x, y, *image::Rgba::from_slice(&amp;[r, r, r, 255]));         green.put_pixel(x, y, *image::Rgba::from_slice(&amp;[g, g, g, 255]));         blue.put_pixel(x, y, *image::Rgba::from_slice(&amp;[b, b, b, 255]));     }     (red, green, blue) }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430, <code>Image::gradient_magnitune<\/code> \u0431\u0435\u0440\u0451\u0442 \u043d\u0430\u0448\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0442\u0438\u0446\u044b \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u044d\u0442\u043e:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/943\/679\/2fd\/9436792fdacb4dd9b9338871bdb8c52a.jpeg\"\/><\/p>\n<h1 id=\"put-naimenshego-soprotivleniya\">\u041f\u0443\u0442\u044c \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f<\/h1>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u043e\u0432\u0430\u0442\u044c, \u043f\u043e\u0436\u0430\u043b\u0443\u0439, \u0441\u0430\u043c\u0443\u044e \u0441\u043b\u043e\u0436\u043d\u0443\u044e \u0447\u0430\u0441\u0442\u044c \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b: DP \u2014 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u0441\u043e\u043f\u0440\u043e\u0442\u0438\u0432\u043b\u0435\u043d\u0438\u044f. \u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0433\u043b\u044f\u043d\u0435\u043c \u043a\u0430\u043a \u044d\u0442\u043e \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c. \u0414\u043b\u044f \u043f\u0440\u043e\u0441\u0442\u043e\u0442\u044b \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u044f, \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0440\u0430\u0441\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0441\u043b\u0443\u0447\u0430\u0439 \u0441 \u043f\u043e\u0438\u0441\u043a\u043e\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u0443\u0442\u0438. \u041f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u044c\u0442\u0435, \u0447\u0442\u043e \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 \u043d\u0438\u0436\u0435 \u044d\u0442\u043e \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f 6\u04456 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439.<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/544\/f84\/26f\/544f8426f4820fa0e1499eff1810d991.svg\" alt=\"$G = \\begin{bmatrix} 1 \\ \\ \\ 4 \\ \\ \\ 3 \\ \\ \\ 4 \\ \\ \\ 2 \\ \\ \\ 1\\\\ 2 \\ \\ \\ 2 \\ \\ \\ 3 \\ \\ \\ 5 \\ \\ \\ 3 \\ \\ \\ 2\\\\ 1 \\ \\ \\ 4 \\ \\ \\ 5 \\ \\ \\ 5 \\ \\ \\ 1 \\ \\ \\ 2\\\\ 4 \\ \\ \\ 4 \\ \\ \\ 3 \\ \\ \\ 1 \\ \\ \\ 5 \\ \\ \\ 3\\\\ 5 \\ \\ \\ 3 \\ \\ \\ 2 \\ \\ \\ 2 \\ \\ \\ 3 \\ \\ \\ 1\\\\ 3 \\ \\ \\ 1 \\ \\ \\ 4 \\ \\ \\ 4 \\ \\ \\ 1 \\ \\ \\ 1 \\end{bmatrix}$\" data-tex=\"display\"\/><\/math><\/p>\n<p>  <\/p>\n<p>\u0421\u0443\u0442\u044c \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0430 \u0441\u043e\u0441\u0442\u043e\u0438\u0442 \u0432 \u043f\u043e\u0438\u0441\u043a\u0435 \u043f\u0443\u0442\u0438 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/d73\/e8d\/1d7\/d73e8d1d752ec8987040495f43aff007.svg\" alt=\"$P=p_1 \\dots\\ p_6$\" data-tex=\"inline\"\/><\/math> \u043e\u0442 \u043e\u0434\u043d\u043e\u0439 \u0438\u0437 \u0432\u0435\u0440\u0445\u043d\u0438\u0445 \u044f\u0447\u0435\u0435\u043a <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/610\/276\/5cf\/6102765cfb9dc896be04aa634484137d.svg\" alt=\"$G_{1i}$\" data-tex=\"inline\"\/><\/math> \u0432 \u043e\u0434\u043d\u0443 \u0438\u0437 \u043d\u0438\u0436\u043d\u0438\u0445 <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/013\/f45\/965\/013f459658c074edf146971e44c27984.svg\" alt=\"$G_{6j}$\" data-tex=\"inline\"\/><\/math> \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043c\u0438\u043d\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c <math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/270\/3d9\/17a\/2703d917a7a88945abe42c053d7299cb.svg\" alt=\"$\\sum_{1 \\leq i \\leq 6} p_i$\" data-tex=\"inline\"\/><\/math>. \u042d\u0442\u043e \u043c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u0441\u0434\u0435\u043b\u0430\u043d\u043e \u043f\u0443\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u044b S \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0440\u0435\u043a\u0443\u0440\u0440\u0435\u043d\u0442\u043d\u043e\u0435 \u0441\u043e\u043e\u0442\u043d\u043e\u0448\u0435\u043d\u0438\u0435 (\u0431\u0435\u0437 \u0443\u0447\u0435\u0442\u0430 \u0433\u0440\u0430\u043d\u0438\u0446\u044b):<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/5bb\/93f\/de4\/5bb93fde429ba771d59b4c7a799e4ec1.svg\" alt=\"$S_{6i} = G_{6i}\\\\\\ S_{ji} = G_{ji} + \\min(S_{j + 1, i - 1}, S_{j + 1, i}, S_{j + 1, i + 1})$\" data-tex=\"display\"\/><\/math><\/p>\n<p>  <\/p>\n<p>\u0422\u043e \u0435\u0441\u0442\u044c, \u043a\u0430\u0436\u0434\u0430\u044f \u044f\u0447\u0435\u0439\u043a\u0430 \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 S \u044d\u0442\u043e \u043c\u0438\u043d\u0438\u043c\u0430\u043b\u044c\u043d\u0430\u044f \u0441\u0443\u043c\u043c\u0430 \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 \u0434\u043e \u0441\u0430\u043c\u043e\u0439 \u043d\u0438\u0436\u043d\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438. \u041a\u0430\u0436\u0434\u0430\u044f \u044f\u0447\u0435\u0439\u043a\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u043e\u0434\u043d\u0443 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0441\u043e\u0441\u0435\u0434\u043d\u0438\u0445 \u044f\u0447\u0435\u0435\u043a, \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u043d\u044b\u0445 \u0441\u0442\u0440\u043e\u043a\u043e\u0439 \u043d\u0438\u0436\u0435, \u0441 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0432\u0435\u0441\u043e\u043c \u2013 \u044d\u0442\u043e \u0438 \u0431\u0443\u0434\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u043e\u0439 \u043f\u0443\u0442\u0438. \u041a\u043e\u0433\u0434\u0430 \u043c\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u043b\u0438 \u0437\u0430\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b S, \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u043c \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u0447\u0438\u0441\u043b\u043e \u0432 \u0441\u0430\u043c\u043e\u0439 \u0432\u0435\u0440\u0445\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0435 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0438.<\/p>\n<p>  <\/p>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0439\u0434\u0435\u043c S:<\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/451\/0ba\/d70\/4510bad705e50e4fc8c15b2c022f1177.svg\" alt=\"$S^{(1)} = \\begin{bmatrix} - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 1 \\end{bmatrix} \\hspace{1cm} S^{(2)} = \\begin{bmatrix} - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 2\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 1 \\end{bmatrix}$\" data-tex=\"display\"\/><\/math><\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/dc4\/66d\/4fb\/dc466d4fb8adbe33927e94ae5cc8bc7b.svg\" alt=\"$S^{(3)} = \\begin{bmatrix} - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ 8 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 5\\\\\\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 2\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 1 \\end{bmatrix} \\hspace{1cm} S^{(4)} = \\begin{bmatrix} - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ 8 \\ \\ \\ \\ \\ 10 \\ \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ 5 \\ \\ \\ \\ \\ 7\\\\\\ 8 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 5\\\\\\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 2\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 1 \\end{bmatrix}$\" data-tex=\"display\"\/><\/math><\/p>\n<p>  <\/p>\n<p><math><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/post_images\/a04\/d0a\/cde\/a04d0acded7d74b783025180ff74d7e6.svg\" alt=\"$S^{(5)} = \\begin{bmatrix} - \\ \\ - \\ \\ - \\ \\ - \\ \\ - \\ \\ -\\\\\\ 10 \\ \\ \\ 10 \\ \\ \\ 12 \\ \\ \\ 10 \\ \\ \\ 8 \\ \\ \\ \\ \\ 7\\\\\\ 8 \\ \\ \\ \\ 10 \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ 5 \\ \\ \\ \\ \\ 7\\\\\\ 8 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 5\\\\\\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 2\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 1 \\end{bmatrix} \\hspace{1cm} S^{(6)} = \\begin{bmatrix} 11 \\ \\ \\ 14 \\ \\ \\ 13 \\ \\ \\ 13 \\ \\ \\ 10 \\ \\ \\ \\textbf{8}\\\\\\ 10 \\ \\ \\ 10 \\ \\ \\ 12 \\ \\ \\ 10 \\ \\ \\ \\ 8 \\ \\ \\ \\ \\textbf{7}\\\\\\ 8 \\ \\ \\ \\ 10 \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ 9 \\ \\ \\ \\ \\ \\textbf{5} \\ \\ \\ \\ \\ 7\\\\\\ 8 \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 6 \\ \\ \\ \\ \\ \\textbf{4} \\ \\ \\ \\ \\ 7 \\ \\ \\ \\ \\ 5\\\\\\ 6 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 3 \\ \\ \\ \\ \\ \\textbf{3} \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 2\\\\\\ 3 \\ \\ \\ \\ \\ 1 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ 4 \\ \\ \\ \\ \\ \\textbf{1} \\ \\ \\ \\ \\ 1 \\end{bmatrix}$\" data-tex=\"display\"\/><\/math><\/p>\n<p>  <\/p>\n<p>\u0418 \u0432\u043e\u0442 \u043e\u043d\u043e! \u041c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u043f\u0443\u0442\u044c, \u0441 \u0441\u0443\u043c\u043c\u043e\u0439 \u0432\u0441\u0435\u0445 \u044f\u0447\u0435\u0435\u043a \u043f\u0443\u0442\u0438 \u0440\u0430\u0432\u043d\u043e\u0439 8, \u0438 \u0442\u043e, \u0447\u0442\u043e \u044d\u0442\u043e\u0442 \u043f\u0443\u0442\u044c \u043d\u0430\u0447\u0438\u043d\u0430\u0435\u0442\u0441\u044f \u0432 \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u043f\u0440\u0430\u0432\u043e\u043c \u0443\u0433\u043b\u0443. \u0414\u043b\u044f \u0442\u043e\u0433\u043e, \u0447\u0442\u043e\u0431\u044b \u043d\u0430\u0439\u0442\u0438 \u043f\u0443\u0442\u044c, \u043c\u044b \u043c\u043e\u0433\u043b\u0438 \u0431\u044b \u0437\u0430\u043f\u043e\u043c\u043d\u0438\u0442\u044c, \u0432 \u043a\u0430\u043a\u0443\u044e \u0441\u0442\u043e\u0440\u043e\u043d\u0443 \u043c\u044b \u043f\u043e\u0448\u043b\u0438 \u0434\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 (\u0432\u043b\u0435\u0432\u043e, \u0432\u043d\u0438\u0437 \u0438\u043b\u0438 \u0432\u043f\u0440\u0430\u0432\u043e), \u043d\u043e \u043d\u0430\u043c \u044d\u0442\u043e \u043d\u0435 \u043d\u0443\u0436\u043d\u043e: \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0432\u044b\u0431\u0435\u0440\u0435\u043c \u0441\u043e\u0441\u0435\u0434\u0430 \u0441\u043d\u0438\u0437\u0443 \u0441 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0432\u0435\u0441\u043e\u043c, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0432\u0435\u0441\u0430 \u043a\u043b\u0435\u0442\u043e\u043a \u0432 \u0442\u0430\u0431\u043b\u0438\u0446\u0435 S \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u044e\u0442 \u043d\u0430 \u043a\u0440\u0430\u0442\u0447\u0430\u0439\u0448\u0438\u0439 \u043f\u0443\u0442\u044c \u043e\u0442 \u0442\u0435\u043a\u0443\u0449\u0435\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 \u043a \u0441\u0430\u043c\u043e\u0439 \u043d\u0438\u0436\u043d\u0435\u0439. \u0422\u0430\u043a\u0436\u0435 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u0435 \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435, \u0447\u0442\u043e \u0435\u0441\u0442\u044c \u0434\u0432\u0430 \u043f\u0443\u0442\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0441\u0443\u043c\u043c\u0435 \u0434\u0430\u044e\u0442 8 (\u0443 \u044d\u0442\u0438\u0445 \u043f\u0443\u0442\u0435\u0439 \u0440\u0430\u0437\u043b\u0438\u0447\u0430\u044e\u0442\u0441\u044f \u0434\u0432\u0435 \u043d\u0438\u0436\u043d\u0438\u0435 \u044f\u0447\u0435\u0439\u043a\u0438).<\/p>\n<p>  <\/p>\n<h1 id=\"realizaciya\">\u0420\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f<\/h1>\n<p>  <\/p>\n<p>\u0422\u0430\u043a-\u043a\u0430\u043a \u043c\u044b \u043f\u0438\u0448\u0435\u043c \u043b\u0438\u0448\u044c \u043c\u0430\u043a\u0435\u0442 \u043f\u0440\u043e\u0433\u0440\u0430\u043c\u043c\u044b, \u0434\u0430\u043b\u044c\u0448\u0435 \u043c\u044b \u0441\u0434\u0435\u043b\u0430\u0435\u043c \u043f\u043e-\u043f\u0440\u043e\u0441\u0442\u043e\u043c\u0443. \u041c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0443 \u0441 \u043d\u0430\u0448\u0435\u0439 \u0442\u0430\u0431\u043b\u0438\u0446\u0435\u0439 \u0432 \u0432\u0438\u0434\u0435 \u043c\u0430\u0441\u0441\u0438\u0432\u0430 \u0438 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u0440\u043e\u0439\u0434\u0435\u043c\u0441\u044f \u043f\u043e \u043d\u0435\u0439 \u0446\u0438\u043a\u043b\u043e\u043c <code>for<\/code> \u0441\u043e\u0433\u043b\u0430\u0441\u043d\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c\u0443.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">struct DPTable {     width: usize,     height: usize,     table: Vec&lt;u16&gt;, }  impl DPTable {     fn from_gradient_buffer(gradient: &amp;GradientBuffer) -&gt; Self {         let dims = gradient.dimensions();         let w = dims.0 as usize;         let h = dims.1 as usize;         let mut table = DPTable {             width: w,             height: h,             table: vec![0; w * h],         };         \/\/ \u0412\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442 gradient[h][w], \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043d\u0430\u043c \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u0442\u044c \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043a\u043e\u0434\u0430         let get = |w, h| gradient.get_pixel(w as u32, h as u32)[0];          \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c \u0441\u0430\u043c\u0443\u044e \u043d\u0438\u0436\u043d\u044e\u044e \u0441\u0442\u0440\u043e\u043a\u0443         for i in 0..w {             let px = get(i, h - 1);             table.set(i, h - 1, px)         }         \/\/ \u0414\u043b\u044f \u043a\u0430\u0436\u0434\u043e\u0439 \u044f\u0447\u0435\u0439\u043a\u0438 \u0432 \u0441\u0442\u0440\u043e\u043a\u0435 J, \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u043c\u0435\u043d\u044c\u0448\u0435\u0435 \u0438\u0437 \u043a\u043b\u0435\u0442\u043a\u0438 \u0432         \/\/ \u0441\u0442\u0440\u043e\u043a\u0435 \u0432\u044b\u0448\u0435. \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0438 \u043a\u043e\u043d\u0446\u0430 \u0441\u0442\u0440\u043e\u043a\u0438         for row in (0..h - 1).rev() {             for col in 1..w - 1 {                 let l = table.get(col - 1, row + 1);                 let m = table.get(col    , row + 1);                 let r = table.get(col + 1, row + 1);                 table.set(col, row, get(col, row) + min(min(l, m), r));             }             \/\/ \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0435 \u0443\u0441\u043b\u043e\u0432\u0438\u044f \u0434\u043b\u044f \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043b\u0435\u0432\u043e\u0439 \u0438 \u043a\u0440\u0430\u0439\u043d\u0435\u0439 \u043f\u0440\u0430\u0432\u043e\u0439:             let left = get(0, row) + min(table.get(0, row + 1), table.get(1, row + 1));             table.set(0, row, left);             let right = get(0, row) + min(table.get(w - 1, row + 1), table.get(w - 2, row + 1));             table.set(w - 1, row, right);         }         table     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0437\u0430\u043f\u0443\u0441\u043a\u0430, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u043f\u0440\u0435\u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u0442\u044c \u0442\u0430\u0431\u043b\u0438\u0446\u0443 <code>DPTable<\/code> \u043e\u0431\u0440\u0430\u0442\u043d\u043e \u0432 <code>GradientBuffer<\/code>, \u0438 \u0437\u0430\u043f\u0438\u0441\u0430\u0442\u044c \u0435\u0433\u043e \u0432 \u0444\u0430\u0439\u043b. \u041f\u0438\u043a\u0441\u0435\u043b\u0438 \u0432 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0438 \u043d\u0438\u0436\u0435 \u2014 \u0432\u0435\u0441\u0430 \u043f\u0443\u0442\u0438, \u0440\u0430\u0437\u0434\u0435\u043b\u0435\u043d\u043d\u044b\u0435 \u043d\u0430 128.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/33b\/b03\/b86\/33bb03b86ef44afd919628c3d1fd9b60.jpeg\"\/>  <\/p>\n<p>  \u042d\u0442\u0443 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443 \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u0442\u0430\u043a: \u0431\u0435\u043b\u044b\u0435 \u043f\u0438\u043a\u0441\u0435\u043b\u0438 \u2014 \u044d\u0442\u043e \u043a\u043b\u0435\u0442\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0438\u043c\u0435\u044e\u0442 \u043d\u0430\u0438\u0431\u043e\u043b\u044c\u0448\u0438\u0439 \u0432\u0435\u0441. \u0413\u0440\u0430\u0434\u0438\u0435\u043d\u0442 \u044d\u0442\u0438\u0445 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u0431\u043e\u043b\u0435\u0435 \u0434\u0435\u0442\u0430\u043b\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u043d, \u0447\u0442\u043e \u0433\u043e\u0432\u043e\u0440\u0438\u0442 \u043e \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0441\u043a\u043e\u0440\u043e\u0441\u0442\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0439 \u0446\u0432\u0435\u0442\u0430 (\u0438 \u0438\u043c\u0435\u043d\u043d\u043e \u044d\u0442\u0438 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u043c\u044b \u0445\u043e\u0442\u0435\u043b\u0438 \u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c).<\/p>\n<p>  <\/p>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u0443\u0442\u0438 \u0431\u0443\u0434\u0435\u0442 \u0438\u0441\u043a\u0430\u0442\u044c \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0438\u0435 \u0432\u0435\u0441\u0430, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u0437\u0434\u0435\u0441\u044c \u201c\u0431\u043e\u043b\u0435\u0435 \u0442\u0435\u043c\u043d\u044b\u043c\u0438 \u043f\u0443\u0442\u044f\u043c\u0438\u201d, \u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0431\u0443\u0434\u0435\u0442 \u0441\u0442\u0430\u0440\u0430\u0442\u044c\u0441\u044f \u0438\u0437\u0431\u0435\u0433\u0430\u0442\u044c \u0441\u0432\u0435\u0442\u043b\u044b\u0445 \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439. \u0422\u043e \u0435\u0441\u0442\u044c \u0431\u0435\u043b\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043a\u0438 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438.<\/p>\n<p>  <\/p>\n<h1 id=\"poisk-puti\">\u041f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438<\/h1>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0432\u0441\u044f \u0442\u0430\u0431\u043b\u0438\u0446\u0430, \u043f\u043e\u0438\u0441\u043a \u043b\u0443\u0447\u0448\u0435\u0433\u043e \u043f\u0443\u0442\u0438 \u043d\u0435 \u0441\u043e\u0441\u0442\u0430\u0432\u0438\u0442 \u0442\u0440\u0443\u0434\u0430: \u044d\u0442\u043e \u2014 \u043f\u0440\u043e\u0441\u0442\u043e \u043f\u043e\u0438\u0441\u043a \u0438\u0437 \u0432\u0435\u0440\u0445\u043d\u0435\u0433\u043e \u0440\u044f\u0434\u0430 \u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0432\u0435\u043a\u0442\u043e\u0440\u0430 \u0438\u043d\u0434\u0435\u043a\u0441\u043e\u0432, \u0432\u0441\u0435\u0433\u0434\u0430 \u0432\u044b\u0431\u0438\u0440\u0430\u044f \u0441\u0430\u043c\u043e\u0433\u043e \u043c\u0430\u043b\u0435\u043d\u044c\u043a\u043e\u0433\u043e \u043f\u043e \u0432\u0435\u0441\u0443 \u0441\u043e\u0441\u0435\u0434\u0430 \u0438\u0437 \u043d\u0438\u0436\u043d\u0435\u0439 \u0441\u0442\u0440\u043e\u043a\u0438:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">impl DPTable {     fn path_start_index(&amp;self) -&gt; usize {         \/\/ \u041f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438 \u0437\u0430\u0448\u0435\u043b \u0441\u043b\u0438\u0448\u043a\u043e\u043c \u0434\u0430\u043b\u0435\u043a\u043e?!         \/\/ \u043f\u043e\u0438\u0441\u043a \u043f\u0443\u0442\u0438 \u043e\u0431\u043b\u0430\u0434\u0430\u0435\u0442 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u043e\u0439.         self.table.iter()             .take(self.width)             .enumerate()             .map(|(i, n)| (n, i))             .min()             .map(|(_, i)| i)             .unwrap()     } }  struct Path {     indices: Vec&lt;usize&gt;, }  impl Path {     pub fn from_dp_table(table: &amp;DPTable) -&gt; Self {         let mut v = Vec::with_capacity(table.height);         let mut col: usize = table.path_start_index();         v.push(col);         for row in 1..table.height {             \/\/ \u0421\u0430\u043c\u044b\u0439 \u043b\u0435\u0432\u044b\u0439, \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0441\u043b\u0435\u0432\u0430.             if col == 0 {                 let m = table.get(col, row);                 let r = table.get(col + 1, row);                 if m &gt; r {                     col += 1;                 }             \/\/ \u0421\u0430\u043c\u044b\u0439 \u043f\u0440\u0430\u0432\u044b\u0439, \u043d\u0435 \u0438\u043c\u0435\u0435\u0442 \u0441\u043e\u0441\u0435\u0434\u0435\u0439 \u0441\u043f\u0440\u0430\u0432\u0430             } else if col == table.width - 1 {                 let l = table.get(col - 1, row);                 let m = table.get(col, row);                 if l &lt; m {                     col -= 1;                 }             } else {                 let l = table.get(col - 1, row);                 let m = table.get(col, row);                 let r = table.get(col + 1, row);                 let minimum = min(min(l, m), r);                 if minimum == l {                     col -= 1;                 } else if minimum == r {                     col += 1;                 }             }             v.push(col + row * table.width);         }          Path {             indices: v         }     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0432\u0438\u0434\u0435\u0442\u044c, \u0447\u0442\u043e \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u043f\u0443\u0442\u0438 \u0431\u043e\u043b\u0435\u0435-\u043c\u0435\u043d\u0435\u0435 \u043f\u0440\u0430\u0432\u0434\u043e\u043f\u043e\u0434\u043e\u0431\u043d\u044b, \u044f \u0441\u0433\u0435\u043d\u0435\u0440\u0438\u0440\u043e\u0432\u0430\u043b \u0438\u0445<br \/>  10 \u0448\u0442\u0443\u043a, \u0438 \u043f\u043e\u043a\u0440\u0430\u0441\u0438\u043b \u0436\u0451\u043b\u0442\u044b\u043c:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/456\/ff2\/0e9\/456ff20e97c341b68397e5d4f49d41cf.jpeg\"\/>  <\/p>\n<p>  \u041f\u043e-\u043c\u043e\u0435\u043c\u0443, \u043f\u043e\u0445\u043e\u0436\u0435 \u043d\u0430 \u043f\u0440\u0430\u0432\u0434\u0443!<\/p>\n<p>  <\/p>\n<h1 id=\"udalenie\">\u0423\u0434\u0430\u043b\u0435\u043d\u0438\u0435<\/h1>\n<p>  <\/p>\n<p>\u0415\u0434\u0438\u043d\u0441\u0442\u0432\u0435\u043d\u043d\u043e\u0435, \u0447\u0442\u043e \u043e\u0441\u0442\u0430\u043b\u043e\u0441\u044c \u0441\u0435\u0439\u0447\u0430\u0441 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u2014 \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u043f\u0443\u0442\u0438, \u043f\u043e\u043a\u0440\u0430\u0448\u0435\u043d\u043d\u044b\u0435 \u0436\u0451\u043b\u0442\u044b\u043c \u0446\u0432\u0435\u0442\u043e\u043c. \u0422\u0430\u043a \u043a\u0430\u043a \u043c\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u0445\u043e\u0442\u0438\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0449\u0435\u0435, \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u043e\u0447\u0435\u043d\u044c \u043f\u0440\u043e\u0441\u0442\u043e: \u0432\u043e\u0437\u044c\u043c\u0451\u043c \u0441\u044b\u0440\u044b\u0435 \u0431\u0430\u0439\u0442\u044b \u0438\u0437 \u043d\u0430\u0448\u0435\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u0441\u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u044b \u043c\u0435\u0436\u0434\u0443 \u0438\u043d\u0434\u0435\u043a\u0441\u0430\u043c\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0432 \u043d\u043e\u0432\u044b\u0439 \u043c\u0430\u0441\u0441\u0438\u0432 \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0438\u0437 \u043d\u0435\u0433\u043e \u043d\u043e\u0432\u043e\u0435 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">impl Image {     fn remove_path(&amp;mut self, path: Path) {         let image_buffer = self.inner.to_rgb();         let (w, h) = image_buffer.dimensions();         let container = image_buffer.into_raw();         let mut new_pixels = vec![];          let mut path = path.indices.iter();         let mut i = 0;         while let Some(&amp;index) = path.next() {             new_pixels.extend(&amp;container[i..index * 3]);             i = (index + 1) * 3;         }         new_pixels.extend(&amp;container[i..]);         let ib = image::ImageBuffer::from_raw(w - 1, h, new_pixels).unwrap();         self.inner = image::DynamicImage::ImageRgb8(ib);     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446 \u043d\u0430\u0441\u0442\u0430\u043b\u043e \u0432\u0440\u0435\u043c\u044f. \u0422\u0435\u043f\u0435\u0440\u044c \u043c\u044b \u043c\u043e\u0436\u0435\u043c \u0443\u0434\u0430\u043b\u0438\u0442\u044c \u0441\u0442\u0440\u043e\u043a\u0443 \u0438\u0437 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0438\u043b\u0438 \u0432\u044b\u0437\u0432\u0430\u0442\u044c \u0432 \u0446\u0438\u043a\u043b\u0435 \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e \u0438 \u0443\u0434\u0430\u043b\u0438\u0442\u044c, \u0441\u043a\u0430\u0436\u0435\u043c, 200 \u0441\u0442\u0440\u043e\u043a:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">let mut image = Image::load_image(path::Path::new(&quot;sample-image.jpg&quot;)); for _ in 0..200 {     let grad = image.gradient_magnitude();     let table = DPTable::from_gradient_buffer(&amp;grad);     let path = Path::from_dp_table(&amp;table);     image.remove_path(path); }<\/code><\/pre>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/988\/33e\/f6b\/98833ef6b7c246b8926c1b65e3c3d604.jpeg\"\/>  <\/p>\n<p>  \u041e\u0434\u043d\u0430\u043a\u043e, \u043c\u044b \u0432\u0438\u0434\u0438\u043c, \u0447\u0442\u043e \u0430\u043b\u0433\u043e\u0440\u0438\u0442\u043c \u0443\u0434\u0430\u043b\u0438\u043b \u043c\u043d\u043e\u0433\u043e\u0432\u0430\u0442\u043e \u0441 \u043f\u0440\u0430\u0432\u043e\u0439 \u0441\u0442\u043e\u0440\u043e\u043d\u044b \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0445\u043e\u0442\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u043e\u043b\u0435\u0435 \u0438\u043b\u0438 \u043c\u0435\u043d\u0435\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u043e, \u044d\u0442\u043e \u043e\u0434\u043d\u0430 \u0438\u0437 \u043f\u0440\u043e\u0431\u043b\u0435\u043c, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043d\u0430\u0434\u043e \u0443\u0441\u0442\u0440\u0430\u043d\u0438\u0442\u044c! \u0411\u044b\u0441\u0442\u0440\u043e\u0435 \u0438 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0433\u0440\u044f\u0437\u043d\u043e\u0435 \u0438\u0441\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0438\u0437\u043c\u0435\u043d\u0438\u0442\u044c \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442, \u043f\u0443\u0442\u0451\u043c \u044f\u0432\u043d\u043e\u0433\u043e \u0437\u0430\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0430\u043d\u0438\u0446 \u043d\u0430 \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u0431\u043e\u043b\u044c\u0448\u043e\u0435 \u0447\u0438\u0441\u043b\u043e, \u0441\u043a\u0430\u0436\u0435\u043c 100.<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/2ec\/133\/2b3\/2ec1332b3f3547a6b0d83d9e50df58d7.jpeg\"\/>  <\/p>\n<p>  \u0422\u0430\u0434\u0430\u043c!<\/p>\n<p>  <\/p>\n<p>\u0417\u0434\u0435\u0441\u044c \u043d\u0435\u043c\u0430\u043b\u043e \u043a\u043e\u0441\u044f\u043a\u043e\u0432, \u0447\u0442\u043e \u0434\u0435\u043b\u0430\u0435\u0442 \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442 \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043c\u0435\u043d\u0435\u0435 \u0443\u0434\u043e\u0432\u043b\u0435\u0442\u0432\u043e\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u0442\u0438\u0447\u043a\u0430 \u043f\u043e\u0447\u0442\u0438 \u043d\u0435 \u043f\u043e\u0441\u0442\u0440\u0430\u0434\u0430\u043b\u0430 \u0438 \u0432\u0435\u043b\u0438\u043a\u043e\u043b\u0435\u043f\u043d\u043e \u0432\u044b\u0433\u043b\u044f\u0434\u0438\u0442 (\u043f\u043e-\u043c\u043e\u0435\u043c\u0443). \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0441\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043c\u044b \u0443\u043d\u0438\u0447\u0442\u043e\u0436\u0438\u043b\u0438 \u0432\u0435\u0441\u044c \u0441\u043c\u044b\u0441\u043b \u043a\u043e\u043c\u043f\u043e\u0437\u0438\u0446\u0438\u0438 \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041d\u0430 \u044d\u0442\u043e \u044f \u0441\u043a\u0430\u0436\u0443\u2026 \u043d\u0443\u0443\u0443\u0443\u2026 \u0442\u0430\u043a-\u0442\u043e \u0434\u0430.<\/p>\n<p>  <\/p>\n<h1 id=\"uvizhu---poveryu\">\u0423\u0432\u0438\u0436\u0443 \u2014 \u043f\u043e\u0432\u0435\u0440\u044e<\/h1>\n<p>  <\/p>\n<p>\u0421\u043e\u0445\u0440\u0430\u043d\u044f\u0442\u044c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0432 \u0444\u0430\u0439\u043b \u0438 \u0441\u043c\u043e\u0442\u0440\u0435\u0442\u044c \u043d\u0430 \u043d\u0438\u0445 \u044d\u0442\u043e \u043f\u0440\u0438\u043a\u043e\u043b\u044c\u043d\u043e, \u043d\u043e \u044d\u0442\u043e \u043d\u0435 \u0441\u0443\u043f\u0435\u0440-\u043a\u0440\u0443\u0442\u043e\u0435-\u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435-\u0440\u0430\u0437\u043c\u0435\u0440\u0430-\u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f-\u0432-\u0440\u0435\u0430\u043b\u044c\u043d\u043e\u043c-\u0432\u0440\u0435\u043c\u0435\u043d\u0438! \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043f\u043e\u043f\u0440\u043e\u0431\u0443\u0435\u043c \u0441\u043e\u0431\u0440\u0430\u0442\u044c \u0432\u0441\u0451 \u0432\u043e\u0435\u0434\u0438\u043d\u043e.<\/p>\n<p>  <\/p>\n<p>\u0412\u043e-\u043f\u0435\u0440\u0432\u044b\u0445, \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u0430 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0442\u044c, \u043f\u043e\u043b\u0443\u0447\u0430\u0442\u044c \u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430. \u041c\u044b \u043f\u043e\u0441\u0442\u0430\u0440\u0430\u0435\u043c\u0441\u044f \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0447\u0442\u043e-\u0442\u043e \u0432\u0440\u043e\u0434\u0435 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u043f\u043b\u0430\u043d\u0430:<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">extern crate content_aware_resize; use content_aware_resize as car;  fn main() {     let mut image = car::load_image(path);     image.resize_to(car::Dimensions::Relative(-1, 0));     let data: &amp;[u8] = image.get_image_data();     \/\/ \u0422\u0430\u043a \u0438\u043b\u0438 \u0438\u043d\u0430\u0447\u0435 \u0432\u044b\u0432\u0435\u0434\u0435\u043c \u044d\u0442\u0438 \u0434\u0430\u043d\u043d\u044b\u0435 \u0432 \u043e\u043a\u043d\u043e }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041c\u044b \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u0440\u043e\u0441\u0442\u043e\u0433\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0441\u0430\u043c\u043e\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0435 \u0438 \u043f\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0441\u043b\u0435\u0434\u0443\u044f \u043a\u043e\u0440\u043e\u0442\u043a\u0438\u043c \u043f\u0443\u0442\u0435\u043c.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">pub enum Dimensions {     Relative(isize, isize), } ... impl Image {     fn size_difference(&amp;self, dims: Dimensions) -&gt; (isize, isize) {         let (w, h) = self.inner.dimensions();         match dims {             Dimensions::Relative(x, y) =&gt; {                 (w as isize + x, h as isize + x)             }         }     }      pub fn resize_to(&amp;mut self, dimensions: Dimensions) {         let (mut xs, mut _ys) = self.size_difference(dimensions);         \/\/ \u041f\u043e\u043a\u0430 \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432         if xs &lt; 0 { panic!(&quot;Only downsizing is supported.&quot;) }         if _ys != 0 { panic!(&quot;Only horizontal resizing is supported.&quot;) }         while xs &gt; 0 {             let grad = self.gradient_magnitude();             let table = DPTable::from_gradient_buffer(&amp;grad);             let path = Path::from_dp_table(&amp;table);             self.remove_path(path);             xs -= 1;         }     }      pub fn get_image_data(&amp;self) -&gt; &amp;[u8] {         self.inner.as_rgb8().unwrap()     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u041f\u0440\u043e\u0441\u0442\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u043a\u043e\u043f\u0438\u043f\u0430\u0441\u0442\u044b! <\/p>\n<p>  <\/p>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e \u043c\u044b \u0445\u043e\u0442\u0438\u043c \u043e\u043a\u043d\u043e \u0438\u0437\u043c\u0435\u043d\u044f\u0435\u043c\u043e\u0433\u043e \u0440\u0430\u0437\u043c\u0435\u0440\u0430. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0431\u044b\u0441\u0442\u0440\u043e \u043d\u0430\u043a\u0438\u0434\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442 \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c \u043a\u043e\u043d\u0442\u0435\u0439\u043d\u0435\u0440\u0430 <code>sdl2<\/code>.<\/p>\n<p>  <\/p>\n<pre><code class=\"rust\">extern crate content_aware_resize; extern crate sdl2; use content_aware_resize as car; use sdl2::rect::Rect; use sdl2::event::{Event, WindowEvent}; use sdl2::keyboard::Keycode; use std::path::Path;  fn main() {     \/\/ \u0417\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443     let mut image = car::Image::load_image(Path::new(&quot;sample-image.jpeg&quot;));     let (mut w, h) = image.dimmensions();      \/\/ \u0418\u043d\u0438\u0446\u0438\u0430\u043b\u0438\u0437\u0438\u0440\u0443\u0435\u043c sdl2 \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043e\u043a\u043d\u043e     let sdl_ctx = sdl2::init().unwrap();     let video = sdl_ctx.video().unwrap();     let window = video.window(&quot;Context Aware Resize&quot;, w, h)         .position_centered()         .opengl()         .resizable()         .build()         .unwrap();      let mut renderer = window.renderer().build().unwrap();      \/\/ \u0423\u0434\u043e\u0431\u043d\u0430\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u044f &quot;\u0442\u0435\u043a\u0441\u0442\u0443\u0440\u044b&quot; \u043f\u0440\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0438 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f     let update_texture = |renderer: &amp;mut sdl2::render::Renderer, image: &amp;car::Image| {         let (w, h) = image.dimmensions();         let pixel_format = sdl2::pixels::PixelFormatEnum::RGB24;         let mut tex = renderer.create_texture_static(pixel_format, w, h).unwrap();         let data = image.get_image_data();         let pitch = w * 3;         tex.update(None, data, pitch as usize).unwrap();         tex     };     let mut texture = update_texture(&amp;mut renderer, &amp;image);      let mut event_pump = sdl_ctx.event_pump().unwrap();     'running: loop {         for event in event_pump.poll_iter() {             \/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0432\u044b\u0445\u043e\u0434\u0430 \u0438 \u0441\u043e\u0431\u044b\u0442\u0438\u0439 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u043e\u0432             match event {                 Event::Quit {..}                 | Event::KeyDown { keycode: Some(Keycode::Escape), .. } =&gt; { break 'running },                 Event::Window {win_event: WindowEvent::Resized(new_w, _h), .. } =&gt; {                     \/\/ \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0438\u043c \u043d\u0430 \u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0438\u043a\u0441\u0435\u043b\u0435\u0439 \u043c\u044b \u0443\u043c\u0435\u043d\u044c\u0448\u0430\u0435\u043c \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0443,                     \/\/ \u0438 \u043d\u0430 \u0441\u0442\u043e\u043b\u044c\u043a\u043e \u0436\u0435 \u0443\u043c\u0435\u043d\u044c\u0448\u0438\u043c \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435                     let x_diff = new_w as isize - w as isize;                     if x_diff &lt; 0 {                         image.resize_to(car::Dimensions::Relative(x_diff, 0));                     }                     w = new_w as u32;                     texture = update_texture(&amp;mut renderer, &amp;image);                 },                 _ =&gt; {}             }         }         \/\/ \u041e\u0447\u0438\u0449\u0430\u0435\u043c, \u043a\u043e\u043f\u0438\u0440\u0443\u0435\u043c \u0438 \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c.         renderer.clear();         renderer.copy(&amp;texture, None, Some(Rect::new(0, 0, w, h))).unwrap();         renderer.present();     } }<\/code><\/pre>\n<p>  <\/p>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0435. \u041e\u0434\u0438\u043d \u0434\u0435\u043d\u044c \u0440\u0430\u0431\u043e\u0442\u044b, \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0437\u043d\u0430\u043d\u0438\u0439 \u043f\u043e <code>sdl2<\/code>, <code>image<\/code>, \u0438 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u043e\u0439 \u043e\u043f\u044b\u0442 \u043d\u0430\u043f\u0438\u0441\u0430\u043d\u0438\u044f \u043f\u043e\u0441\u0442\u043e\u0432 \u0432 \u0431\u043b\u043e\u0433\u0435.<\/p>\n<p>  <\/p>\n<p>\u041d\u0430\u0434\u0435\u044e\u0441\u044c \u0432\u0430\u043c \u043f\u043e\u043d\u0440\u0430\u0432\u0438\u043b\u043e\u0441\u044c, \u0445\u043e\u0442\u044f \u0431\u044b \u0441\u043e\u0432\u0441\u0435\u043c \u043d\u0435\u043c\u043d\u043e\u0436\u043a\u043e \ud83d\ude42<\/p>\n<p>  <\/p>\n<ul>\n<li><a href=\"https:\/\/www.github.com\/martinhath\/content-aware-resize\">\u0420\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0439 Git<\/a><\/li>\n<li><a href=\"https:\/\/www.reddit.com\/r\/rust\/comments\/5ttzb4\/implementing_content_aware_image_resizing\/\">\u0412\u0435\u0442\u043a\u0430 \/r\/Rust<\/a><\/li>\n<li><a href=\"https:\/\/www.reddit.com\/r\/programming\/comments\/5ttz9g\/implementing_content_aware_image_resizing\/\">\u0412\u0435\u0442\u043a\u0430 \/r\/Programming<\/a><\/li>\n<li><a href=\"https:\/\/news.ycombinator.com\/item?id=13636706\">HackerNews<\/a><\/li>\n<\/ul>\n<p>  <\/p>\n<hr\/>\n<p>  <\/p>\n<ol>\n<li>\u041f\u043e\u0447\u0435\u043c\u0443-\u0442\u043e, duckduck-\u043a\u043e\u0435\u0434 \u043d\u0435 \u0440\u0430\u0431\u043e\u0442\u0430\u0435\u0442, \u0438 \u0433\u0443\u0433\u043b\u044c \u0442\u043e\u0436\u0435, \u0435\u0441\u043b\u0438 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442\u0441\u044f \u0433\u043b\u0430\u0433\u043e\u043b.<a href=\"#top1\">[\u2191]<\/a><\/li>\n<li><a href=\"http:\/\/imgsv.imaging.nikon.com\/lineup\/lens\/zoom\/normalzoom\/af-s_dx_18-140mmf_35-56g_ed_vr\/img\/sample\/sample1_l.jpg\">http:\/\/imgsv.imaging.nikon.com\/lineup\/lens\/zoom\/normalzoom\/af-s_dx_18-140mmf_35-56g_ed_vr\/img\/sample\/sample1_l.jpg<\/a> <a href=\"#ref2ret\">[\u2191]<\/a><\/li>\n<li>\u041c\u043d\u0435 \u0438\u043d\u0442\u0435\u0440\u0435\u0441\u043d\u043e, \u0435\u0441\u0442\u044c \u043b\u0438 \u0431\u043e\u043b\u0435\u0435 \u043f\u0440\u043e\u0441\u0442\u043e\u0439 \u0441\u043f\u043e\u0441\u043e\u0431! \u041a\u0440\u043e\u043c\u0435 \u0442\u043e\u0433\u043e,<br \/>  \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u0435 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u0430 \u0433\u0440\u0430\u0434\u0438\u0435\u043d\u0442\u0430 \u043f\u043e\u0445\u043e\u0434\u0443 \u043d\u0435\u0440\u0435\u0430\u043b\u044c\u043d\u043e, \u043f\u043e\u0442\u043e\u043c\u0443-\u0447\u0442\u043e \u0444\u0443\u043d\u043a\u0446\u0438\u044f \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442<br \/>  <code>ImageBuffer<\/code> \u043f\u043e\u0432\u0435\u0440\u0445 <code>u16<\/code>, \u0432 \u0442\u043e \u0432\u0440\u0435\u043c\u044f \u043a\u0430\u043a <code>ImageBuffer::save<\/code> \u0442\u0440\u0435\u0431\u0443\u0435\u0442, \u0447\u0442\u043e\u0431\u044b<br \/>  \u043e\u0441\u043d\u043e\u0432\u043d\u044b\u0435 \u0434\u0430\u043d\u043d\u044b\u0435 \u0431\u044b\u043b\u0438 \u0432 <code>u8<\/code>. \u042f \u0442\u0430\u043a\u0436\u0435 \u043d\u0435 \u043c\u043e\u0433 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0442\u044c<br \/>  <code>DynamicImage<\/code> (\u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e \u0442\u0430\u043a\u0436\u0435 \u0435\u0441\u0442\u044c <code>a::save<\/code> \u0441 \u0431\u043e\u043b\u0435\u0435 \u043f\u043e\u043d\u044f\u0442\u043d\u044b\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c)<br \/>  \u043e\u0442 <code>ImageBuffer<\/code>, \u0432\u0435\u0434\u044c \u044d\u0442\u043e \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e. <a href=\"#ref3ret\">[\u2191]<\/a><\/li>\n<\/ol>\n<p>  <\/p>\n<h1 id=\"primechanie-perevodchika\">\u041f\u0440\u0438\u043c\u0435\u0447\u0430\u043d\u0438\u0435 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0447\u0438\u043a\u0430<\/h1>\n<p>  <\/p>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044e \u0432\u0441\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u043e \u0440\u0443\u0441\u0441\u043a\u043e\u044f\u0437\u044b\u0447\u043d\u044b\u0445 \u0440\u0430\u0441\u0442\u0430\u043c\u0430\u043d\u043e\u0432 <a href=\"https:\/\/gitter.im\/ruRust\/general\">ruRust<\/a><br \/>  \u0412\u044b\u0440\u0430\u0436\u0430\u044e \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u0443\u044e \u0431\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u043d\u043e\u0441\u0442\u044c:<\/p>\n<p>  <\/p>\n<ul>\n<li>\u0421\u0435\u0440\u0433\u0435\u044e \u0412\u0435\u0441\u0435\u043b\u043a\u043e\u0432\u0443 (@vessd)<\/li>\n<li>\u0418\u0433\u043e\u0440\u044e (@Gordon-F)<\/li>\n<li>\u041c\u0438\u0445\u0430\u0438\u043b\u0443 \u041f\u0430\u043d\u043a\u043e\u0432\u0443 (@mkpankov)<br \/>  \u0430 \u0442\u0430\u043a \u0436\u0435:<\/li>\n<li>\u0428\u0435\u0440\u0437\u043e\u0434\u0443 \u041c\u0443\u0442\u0430\u043b\u043e\u0432\u0443 (@shmutalov)<\/li>\n<li>\u0410\u043d\u0434\u0440\u0435\u044e \u041b\u0435\u0441\u043d\u0438\u043a\u043e\u0432\u0443 (@ozkiff) \u0437\u0430 \u043f\u043e\u043c\u043e\u0449\u044c \u0432 \u043f\u0435\u0440\u0435\u0432\u043e\u0434\u0435 \u0438 \u043f\u043e\u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435 \u0440\u0435\u0432\u044c\u044e.<\/li>\n<\/ul>\n<p> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habrahabr.ru\/post\/324284\/\"> https:\/\/habrahabr.ru\/post\/324284\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e (Content Aware Image Resize), \u0436\u0438\u0434\u043a\u043e\u0435 \u0440\u0430\u0441\u0442\u044f\u0436\u0435\u043d\u0438\u0435 (liquid resizing), \u0440\u0435\u0442\u0430\u0440\u0433\u0435\u0442\u0438\u043d\u0433 (retargeting) \u0438\u043b\u0438 \u0432\u044b\u0440\u0435\u0437\u0430\u043d\u0438\u0435 \u0448\u0432\u0430 (seam carving) \u043e\u0442\u043d\u043e\u0441\u044f\u0442\u0441\u044f \u043a \u043c\u0435\u0442\u043e\u0434\u0443 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f, \u0433\u0434\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u043b\u0438 \u0443\u0434\u0430\u043b\u044f\u0442\u044c <em>\u0448\u0432\u044b<\/em>, \u0438\u043b\u0438 \u043d\u0430\u0438\u043c\u0435\u043d\u0435\u0435 \u0432\u0430\u0436\u043d\u044b\u0435 \u043f\u0443\u0442\u0438, \u0434\u043b\u044f \u0443\u043c\u0435\u043d\u044c\u0448\u0435\u043d\u0438\u044f \u0438\u043b\u0438 \u043d\u0430\u0440\u0430\u0449\u0438\u0432\u0430\u043d\u0438\u044f \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f. \u041e\u0431 \u044d\u0442\u043e\u0439 \u0438\u0434\u0435\u0435 \u044f \u0443\u0437\u043d\u0430\u043b \u0438\u0437 <a href=\"https:\/\/www.youtube.com\/watch?v=qadw0BRKeMk\">\u0440\u043e\u043b\u0438\u043a\u0430 \u043d\u0430 YouTube<\/a>, \u043e\u0442 Shai Avidan \u0438 Ariel Shamir.<\/p>\n<p>  <\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0435 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0430 \u043f\u0440\u043e\u0441\u0442\u0430\u044f \u043f\u0440\u043e\u0431\u043d\u0430\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0438\u0434\u0435\u0438 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0438\u0437\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0441 \u0443\u0447\u0451\u0442\u043e\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0433\u043e, \u0435\u0441\u0442\u0435\u0441\u0442\u0432\u0435\u043d\u043d\u043e \u043d\u0430 \u044f\u0437\u044b\u043a\u0435 Rust \ud83d\ude42<\/p>\n<p>  <\/p>\n<p>\u0414\u043b\u044f \u043f\u043e\u0434\u043e\u043f\u044b\u0442\u043d\u043e\u0439 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438, \u044f \u043f\u043e\u0438\u0441\u043a\u0430\u043b \u043f\u043e \u0437\u0430\u043f\u0440\u043e\u0441\u0443<sup><a rel=\"footnote\" href=\"#fn:duckduck\">1<\/a><\/sup> <code>&quot;sample image&quot;<\/code>, \u0438 \u043d\u0430\u0448\u0435\u043b \u0435\u0451<sup><a href=\"#myfootnote2\">2<\/a><\/sup>:<\/p>\n<p>  <img decoding=\"async\" src=\"https:\/\/habrastorage.org\/files\/63d\/4b1\/dc3\/63d4b1dc37d4495c8aa36c931a30b02b.jpeg\"\/>  <\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-283496","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/283496","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=283496"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/283496\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=283496"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=283496"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=283496"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}