日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

图像处理(二)Seam Carving算法-Siggraph 2007

發布時間:2025/3/21 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 图像处理(二)Seam Carving算法-Siggraph 2007 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Seam Carving 算法是2007年siggraph上的一篇paper,名為《Seam Carving for Content-Aware Image Resizing》,這篇paper提出了一種內容感知的圖像縮放算法,繼這篇paper的思想,后來近幾年siggraph上面也有好幾篇都是內容感知的圖像縮放算法。內容感知的圖像縮放算法一般用于圖像的裁剪,就是有的時候,你覺得一張照片有點大,你希望把它裁剪的小一些,但是你又想保留照片中的物體,這個時候就要用到內容感知的突刺昂縮放算法了。

? ??
原圖 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 裁剪結果
垂直方向裁剪
該開始學習這個算法的時候,看起來好像很高深莫測的樣子,理論看起來好像牛逼哄哄,什么能量,動態規劃,都把我嚇到了,最后理論的東西我實在是受不鳥了,于是果斷直接解讀代碼,看了代碼以后,才知道這個算法其實非常簡單,難度就比普通的圖像縮放難那么一點點,其實算法的原理很簡單。廢話不多說,這邊只介紹縮小算法,且是圖像寬度縮小的算法,對于圖像高度縮小,只需對圖像轉置處理,總之paper中其它功能的實現,大同小異,整個過程說的簡單一點就是通過尋找一條線,如上面的圖1所示,找到了線以后,把那條線上的像素點全部刪除,從而實現縮小操作。

該過程是通過迭代實現的,每次只能移除一列,迭代直到寬度滿足要求。下面介紹尋找移除能量線的方法,需要注意的是,每次移除一列,都要重新計算能量圖,也就是說,梯度圖要重新計算,才能進行下一輪的移除工作。

算法流程

1、算法第一步計算圖像能量圖?

能量圖一般是圖像像素的梯度模值,為了簡化計算可先轉換成灰度圖像,然后直接采用如下公式(直接用x、y方向上的差分取絕對值,然后相加),其實這一步就是相當于邊緣檢測算法一樣:


2、算法第二步尋找最小能量線

最小能量線指的是需要被移除的那一列:首先需要以圖像第一行或最后一行為開始行進行迭代。下面實現的為從圖像最后一行開始,往上迭代,

?

[c++]?view plaincopy
  • //先找出圖片最底部的一行中,能量最小的像素點作為起始點??
  • int?min_x?=?0;??
  • int?width?=?(*Source).Width();??
  • int?height?=?(*Source).Height();??
  • for(?int?x?=?0;?x?<?width;?x++?)??
  • {??
  • ????if(?(*Source)(x,height-1)->energy?<?(*Source)(min_x,height-1)->energy?)??
  • ????{??
  • ????????min_x?=?x;??
  • ????}??
  • }??
  • 找出最后一行需要被移除的像素點后,設其坐標為P(x,y),然后往上一行尋找,尋找的點為P點的在y-1行中的三個相鄰像素點中的能量最小值像素。也就是尋找的坐標為(x-1,y-1)、(x,y-1)、(x+1,y-1);

    ?

    [c++]?view plaincopy
  • ?//min_x是圖片最底部的一行的能量值最小的像素點?因此遍歷的時候,要往上尋找??
  • void?Generate_Path(?CML_image_ptr?*?Energy,?int?min_x,?int?*?Path?)??
  • {??
  • ????int?min;??
  • ????int?x?=?min_x;//起始行的能量最小點??
  • ????int?height?=?(*Energy).Height();??
  • //從底部往上尋找最小能量線??
  • ????for(?int?y?=?height?-?1;?y?>=?0;?y--?)?//從下往上??
  • ????{??
  • ????????min?=?x;?//首個頂點迭代更新??
  • ????????//計算上一行中??三個鄰接像素中能量值最小的像素點?作為上一行的能量最小點??
  • ????????int?Maxy=??Get_Max(?Energy,?min,?y?);??
  • ????????if(?Get_Max(?Energy,?x-1,?y?)?<?Maxy?)?//??
  • ????????{??
  • ????????????min?=?x?-?1;??
  • ????????}??
  • ????????if(?Get_Max(?Energy,?x+1,?y?)?<?Maxy?)?//up-right??
  • ????????{??
  • ????????????min?=?x?+?1;??
  • ????????}??
  • ????????Path[y]?=?min;??
  • ????????x?=?min;??
  • ????}??
  • }??
  • 3、算法第三步:移除得到的最小能量線,讓圖片的寬度縮小一個像素

    移除最小能量線,同時所有位于最小能量線右邊的像素點左移一個單位,從而實現圖像縮小寬度縮小一個單位。

    移除的時候?為了讓圖像看起來自然,需要在移除縫線的地方進行平均,假設移除坐標為P(x,y),那么移除后P(x-1,y)的像素值為P(x-1,y)與P(x,y)的像素值的平均。P(x+1,y)的像素值為P(x-1,y)與P(x,y)的像素值的平均,然后才能把P(x+1,y)移動到P(x,y)的位置。

    ?

    [c++]?view plaincopy
  • int?height=(*Source).Height();??
  • ????int?width=(*Source).Width();??
  • ????//移除函數??
  • ????for(?int?y?=0;?y?<?height;?y++?)??
  • ????{??
  • ????????int?remove?=?(Path)[y];??
  • ????????(*(Source))(remove,y)->removed?=?true;??
  • ????????//移除的時候?為了讓圖像看起來自然,需要在移除縫線的地方進行平均,假設移除坐標為P(x,y),那么??
  • ????????//移除后P(x-1,y)的像素值為P(x-1,y)與P(x,y)的像素值的平均??
  • ????????//P(x+1,y)的像素值為P(x-1,y)與P(x,y)的像素值的平均,然后才能把P(x+1,y)移動到P(x,y)的位置??
  • ????????if(?(remove?-?1)?>?0?)??
  • ????????{??
  • ????????????if(?(*(Source))(remove,y)->weight?>=?0?)??
  • ????????????{??
  • ????????????????(*(Source))(remove-1,y)->image?=?Average_Pixels(?(*(Source))(remove,y)->image,??
  • ????????????????????(*(Source)).Get(remove-1,y)->image?);??
  • ????????????}??
  • ????????????(*(Source))(remove-1,y)->gray?=?Grayscale_Pixel(?&(*(Source))(remove-1,y)->image?);??
  • ????????}??
  • ??
  • ????????if(?(remove?+?1)?<?(*(Source)).Width()?)??
  • ????????{??
  • ????????????if(?(*(Source))(remove,y)->weight?>=?0?)???
  • ????????????{??
  • ????????????????(*(Source))(remove+1,y)->image?=?Average_Pixels(?(*(Source))(remove,y)->image,??
  • ????????????????????(*(Source)).Get(remove+1,y)->image?);??
  • ????????????}??
  • ????????????(*(Source))(remove+1,y)->gray?=?Grayscale_Pixel(?&(*(Source))(remove+1,y)->image?);??
  • ????????}??
  • ????????(*(Source)).Shift_Row(?remove?+?1,?y,?-1?);??
  • ????}??
  • ?對于圖像的放大算法原理一樣,先找到最小能量線,設能量線上點的坐標為P(x,y),則在P(x,y)、P(x+1,y)中心位置插入新的像素,像素值為P(x,y)與P(x+1,y)的平均。本文地址:http://blog.csdn.net/hjimce/article/details/44916869?? ?作者:hjimce ? ? 聯系qq:1393852684 ? ? ? ? ? ? ?更多資源請關注我的博客:http://blog.csdn.net/hjimce? ? ? ? ? ? ? ? ?原創文章,版權所有,轉載請保留這幾行信息

    總結

    以上是生活随笔為你收集整理的图像处理(二)Seam Carving算法-Siggraph 2007的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。