<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                合規國際互聯網加速 OSASE為企業客戶提供高速穩定SD-WAN國際加速解決方案。 廣告
                在上一個學習筆記中,簡單介紹了訪問圖像像素的幾種方法,并對這幾種方法的效率進行了些簡單的比較。但是更多的情況是我們要同時訪問多個像素,經過較為復雜的運算才能得到我們希望的結果。今天就來講講這種情況如何處理。 ### 同時訪問多行像素數據 下面我們以laplace 銳化為例,Laplacian 算子寫為矩陣形式如下: ???0?10?15?10?10??? 可以看到,計算當前點的輸出時需要上下左右 4 鄰近點的值。這時最簡單的想法就是同時用三個指針,分別指向當前行、上一行和下一行。下面是個例子代碼: ~~~ void sharpen(const cv::Mat &image, cv::Mat &result) { // allocate if necessary result.create(image.size(), image.type()); for (int j = 1; j < image.rows - 1; j++) { // for all rows // (except first and last) const uchar* previous = image.ptr<const uchar>(j-1); // previous row const uchar* current = image.ptr<const uchar>(j); // current row const uchar* next = image.ptr<const uchar>(j+1); // next row uchar* output= result.ptr<uchar>(j); // output row for (int i=1; i<image.cols-1; i++) { *output++= cv::saturate_cast<uchar>( 5 *current[i] - current[i-1] - current[i+1] - previous[i] - next[i]); } } // Set the unprocess pixels to 0 result.row(0).setTo(cv::Scalar(0)); result.row(result.rows-1).setTo(cv::Scalar(0)); result.col(0).setTo(cv::Scalar(0)); result.col(result.cols-1).setTo(cv::Scalar(0)); } ~~~ 有幾點需要說明: 1. 這個函數只對灰度圖像有效。 1. 應為對原始圖像我們只是讀取而不改變其值,所以用的是 const uchar* 型的指針。 1. 運算結果有可能會超出 uchar 型能夠表示的范圍,所以程序中用了 cv::saturate_cast () 將超出的部分截斷。 1. 圖像的四條邊框沒有計算,而是直接填充了 0 值。 原始圖像和處理后的圖像對比如下: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db48b508.jpg "") ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db4b40e2.jpg "") 如果要處理彩色圖像,可以這樣寫: ~~~ void sharpen1(const cv::Mat &image, cv::Mat &result) { // allocate if necessary result.create(image.size(), image.type()); int nr = image.rows; int nl = image.cols; for (int j = 1; j < nr - 1; j++) { // for all rows // (except first and last) const cv::Vec3b* previous = image.ptr<const cv::Vec3b>(j-1); // previous row const cv::Vec3b* current = image.ptr<const cv::Vec3b>(j); // current row const cv::Vec3b* next = image.ptr<const cv::Vec3b>(j+1); // next row cv::Vec3b* output= result.ptr<cv::Vec3b>(j); // output row for (int i = 1; i<nl - 1; i++) { output[i][0] = cv::saturate_cast<uchar>( 5 *current[i][0] - current[i - 1][0] - current[i + 1][0] - previous[i][0] - next[i][0]); output[i][1] = cv::saturate_cast<uchar>( 5 *current[i][1] - current[i - 1][1] - current[i + 1][1] - previous[i][1] - next[i][1]); output[i][2] = cv::saturate_cast<uchar>( 5 *current[i][2] - current[i - 1][2] - current[i + 1][2] - previous[i][2] - next[i][2]); } } // Set the unprocess pixels to 0 result.row(0).setTo(cv::Vec3b(0, 0, 0)); result.row(result.rows-1).setTo(cv::Vec3b(0, 0, 0)); result.col(0).setTo(cv::Vec3b(0, 0, 0)); result.col(result.cols-1).setTo(cv::Vec3b(0, 0, 0)); } ~~~ 或者還是用 uchar 型來處理: ~~~ void sharpen2(const cv::Mat &image, cv::Mat &result) { // allocate if necessary result.create(image.size(), image.type()); int nr = image.rows; int nl = image.cols * image.elemSize(); int stride = image.elemSize(); for (int j = 1; j < nr - 1; j++) { // for all rows // (except first and last) const uchar* previous = image.ptr<const uchar>(j-1); // previous row const uchar* current = image.ptr<const uchar>(j); // current row const uchar* next = image.ptr<const uchar>(j+1); // next row uchar* output= result.ptr<uchar>(j); // output row for (int i = stride; i < nl - stride; i++) { *output++= cv::saturate_cast<uchar>( 5 *current[i] - current[i - stride] - current[i + stride] - previous[i] - next[i]); } } // Set the unprocess pixels to 0 result.row(0).setTo(cv::Vec3b(0, 0, 0)); result.row(result.rows-1).setTo(cv::Vec3b(0, 0, 0)); result.col(0).setTo(cv::Vec3b(0, 0, 0)); result.col(result.cols-1).setTo(cv::Vec3b(0, 0, 0)); } ~~~ 實際上,上面的操作還可以使用 cv::filter2D 函數來做。代碼會非常簡潔,而且計算速度也是最快的。 ~~~ void sharpen2D(const cv::Mat &image, cv::Mat &result) { // Construct kernel (all entries initialized to 0) cv::Mat kernel(3, 3, CV_32F, cv::Scalar(0)); // assigns kernel values kernel.at<float>(1,1) = 5.0; kernel.at<float>(0,1) = -1.0; kernel.at<float>(2,1) = -1.0; kernel.at<float>(1,0) = -1.0; kernel.at<float>(1,2) = -1.0; //filter the image cv::filter2D(image, result, image.depth(), kernel); } ~~~ 處理前后的圖像對比如下: ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db4e71c1.jpg "") ![這里寫圖片描述](https://box.kancloud.cn/2016-04-26_571f1db518b00.jpg "")
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看