OpenCV isContinuous()连续存储的问题
生活随笔
收集整理的這篇文章主要介紹了
OpenCV isContinuous()连续存储的问题
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
OpenCV isContinuous()連續存儲的問題
【尊重原創,轉載請注明出處】http://blog.csdn.net/guyuealian/article/details/78614662
一、OpenCV isContinuous()函數:
定義: bool cv::Mat::isContinuous() const說明: ? ? ?報告矩陣是否連續。 ? ? ?如果矩陣元素在每行末尾連續存儲而沒有間隙,則方法返回true。 否則,它返回false。 顯然,對于1x1或1xN矩陣總是連續的。一般 用Mat :: create創建的矩陣總是連續的。 但是,如果使用Mat :: col,Mat :: diag等提取矩陣的一部分,或者為外部分配的數據構造矩陣頭,則此類矩陣可能不再具有此屬性。 ? ? ?連續性標志存儲在Mat :: flags字段中,并在構造矩陣標題時自動計算。 因此,連續性檢查是一個非??斓牟僮?#xff0c;雖然理論上可以這樣做:
// alternative implementation of Mat::isContinuous() bool myCheckMatContinuity(const Mat& m) {//return (m.flags & Mat::CONTINUOUS_FLAG) != 0;return m.rows == 1 || m.step == m.cols*m.elemSize();//檢測內存存儲連續性 }? ??這個isContinuous方法在很多OpenCV函數中都有使用。 重點在于元素操作(例如算術和邏輯操作,數學函數,alpha?混合,顏色空間變換等)不依賴于圖像幾何。 因此,如果所有的輸入和輸出數組都是連續的,那么函數可以將它們處理為非常長的單行向量。 下面的例子說明了如何實現一個alpha混合(透明混合)函數:
template<typename T> void alphaBlendRGBA(const Mat& src1, const Mat& src2, Mat& dst) {const float alpha_scale = (float)std::numeric_limits<T>::max(),inv_scale = 1.f/alpha_scale;CV_Assert( src1.type() == src2.type() &&src1.type() == CV_MAKETYPE(DataType<T>::depth, 4) &&src1.size() == src2.size());Size size = src1.size();dst.create(size, src1.type());// here is the idiom: check the arrays for continuity and,// if this is the case,// treat the arrays as 1D vectorsif( src1.isContinuous() && src2.isContinuous() && dst.isContinuous() ){size.width *= size.height;size.height = 1;}size.width *= 4;for( int i = 0; i < size.height; i++ ){// when the arrays are continuous,// the outer loop is executed only onceconst T* ptr1 = src1.ptr<T>(i);const T* ptr2 = src2.ptr<T>(i);T* dptr = dst.ptr<T>(i);for( int j = 0; j < size.width; j += 4 ){float alpha = ptr1[j+3]*inv_scale, beta = ptr2[j+3]*inv_scale;dptr[j] = saturate_cast<T>(ptr1[j]*alpha + ptr2[j]*beta);dptr[j+1] = saturate_cast<T>(ptr1[j+1]*alpha + ptr2[j+1]*beta);dptr[j+2] = saturate_cast<T>(ptr1[j+2]*alpha + ptr2[j+2]*beta);dptr[j+3] = saturate_cast<T>((1 - (1-alpha)*(1-beta))*alpha_scale);}} }? ? ?這種方法雖然非常簡單,但是可以將簡單元素操作的性能提高10-20%,特別是如果圖像相當小并且操作非常簡單。
? ? ?在這個函數中的另一個OpenCV習慣用法,調用目標數組的Mat :: create,除非它已經具有適當的大小和類型,否則分配目標數組。 而新分配的數組總是連續的,你仍然需要檢查目標數組,因為Mat :: create并不總是分配一個新的矩陣。 ? ? ?用Mat存儲一幅圖像時,若圖像在內存中是連續存儲的(Mat對象的isContinuous == true),則可以將圖像的數據看成是一個一維數組,而data(uchar*)成員就是指向圖像數據的第一個字節的,因此可以用data指針訪問圖像的數據,從而加速Mat圖像的訪問速度。
? ? ?一般經過裁剪的Mat圖像,都不再連續了,如cv::Mat crop_img = src(rect);crop_img 是不連續的Mat圖像,如果想轉為連續的,最簡單的方法,就是將不連續的crop_img 重新clone()一份給新的Mat就是連續的了,如:
Mat src = imread("D:\\OpencvTest\\B1.jpg");//原始圖像是200*200 cv::imshow("src", src);printf("---src.isContinuous=%d", src.isContinuous()); printf("\n");//直接imread的Mat是連續的cv::Rect rect(1, 1, 100, 100);cv::Mat crop_img = src(rect);//裁剪后的圖像是不連續的cv::imshow("crop_img", crop_img);printf("---crop_img.isContinuous=%d", crop_img.isContinuous()); printf("\n");cv::Mat crop_img2;//crop_img2.create(crop_img2.size(), crop_img2.type());crop_img2 = crop_img.clone();//重新clone()后的圖像是連續的printf("---crop_img2.isContinuous=%d", crop_img2.isContinuous()); printf("\n"); 運行結果:顯然,裁剪后的Mat圖像不再連續,而重新clone()一份后又連續了.
? ? ??
總結
以上是生活随笔為你收集整理的OpenCV isContinuous()连续存储的问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: OpenCV android sdk配置
- 下一篇: C/C++结构体struct 与结构体数