場景需求
在做影像處理時,有時候會需要適當地進行一些裁剪作業,比如我做干涉測量領域,我們所要處理的影像區域是條紋所在區域,而原圖又遠大于我所想分析的目標區,此時就需要對影像進行裁剪,這樣做的好處:
1)縮減計算量,提高程式運行速度;
2)裁剪后的影像尺寸正好是歸一化的影像尺寸,如果有歸一化的需求,可以直接用裁剪影像尺寸建立歸一化資料網格圖,
我就是為了計算柱面的擬合系數才寫了這個函式,若要得到同光學領域標準一致的系數,需要先歸一化資料,而歸一化的范圍就正好是裁剪的影像大小,
函式通俗易懂,就是用掩膜鎖定目標區,再分析掩膜在原圖中的上下左右邊界,用roi提取出來即可,
話不多說,下方為具體實作函式和測驗代碼,
功能函式代碼
/**
* @brief ImageCropping 影像裁剪
* @param phase 所需裁剪的影像
* @return 裁剪后影像
*/
cv::Mat ImageCropping(const cv::Mat &phase) {
// 非測量區一般都進行了NaN處理,所以掩膜繪制只需要判斷是否為NaN值即可
cv::Mat mask = cv::Mat::zeros(phase.size(), CV_8UC1);
mask.setTo(255, phase == phase);
int roi_up = 10000;
int roi_down = 0;
int roi_left = 10000;
int roi_right = 0;
int row = phase.rows;
int col = phase.cols;
for (int i = 0; i < row; i++)
{
uchar *m = mask.ptr<uchar>(i);
for (int j = 0; j < col; j++)
{
if (m[j] != 0)
{
if (j < roi_left)roi_left = j;
if (j > roi_right)roi_right = j;
if (i < roi_up)roi_up = i;
if (i > roi_down)roi_down = i;
}
}
}
int w = roi_right - roi_left;
int h = roi_down - roi_up;
// 一般提取奇數尺寸,方便計算
if (w % 2 == 0)w++;
if (h % 2 == 0)h++;
cv::Mat crop_phase = phase(cv::Rect(roi_left, roi_up, w, h)).clone();
return crop_phase;
}
C++測驗代碼
#include<iostream>
#include<opencv2/opencv.hpp>
#include<ctime>
using namespace std;
using namespace cv;
cv::Mat ImageCropping(const cv::Mat &phase);
int main(void)
{
cv::Mat phase(100, 100, CV_32FC1, nan(""));
cv::circle(phase, cv::Point(50, 50), 30, 255, -1);
cv::Mat crop = ImageCropping(phase);
imshow("original", phase);
imshow("result", crop);
waitKey(0);
system("pause");
return 0;
}
/**
* @brief ImageCropping 影像裁剪
* @param phase 所需裁剪的影像
* @return 裁剪后影像
*/
cv::Mat ImageCropping(const cv::Mat &phase) {
// 非測量區一般都進行了NaN處理,所以掩膜繪制只需要判斷是否為NaN值即可
cv::Mat mask = cv::Mat::zeros(phase.size(), CV_8UC1);
mask.setTo(255, phase == phase);
int roi_up = 10000;
int roi_down = 0;
int roi_left = 10000;
int roi_right = 0;
int row = phase.rows;
int col = phase.cols;
for (int i = 0; i < row; i++)
{
uchar *m = mask.ptr<uchar>(i);
for (int j = 0; j < col; j++)
{
if (m[j] != 0)
{
if (j < roi_left)roi_left = j;
if (j > roi_right)roi_right = j;
if (i < roi_up)roi_up = i;
if (i > roi_down)roi_down = i;
}
}
}
int w = roi_right - roi_left;
int h = roi_down - roi_up;
// 一般提取奇數尺寸,方便計算
if (w % 2 == 0)w++;
if (h % 2 == 0)h++;
cv::Mat crop_phase = phase(cv::Rect(roi_left, roi_up, w, h)).clone();
return crop_phase;
}
測驗效果
在測驗案例中,隨機生成了一個100*100的資料矩陣,中間一個30半徑的圓,也是我需要的目標區域,運用ImageCropping函式實作了目標區域的提取,
如果函式有什么可以改進完善的地方,非常歡迎大家指出,一同進步何樂而不為呢~
如果文章幫助到你了,可以點個贊讓我知道,我會很快樂~加油!
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/292453.html
標籤:其他
