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

歡迎訪問 生活随笔!

生活随笔

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

编程问答

OpenCV isContinuous()连续存储的问题

發(fā)布時間:2024/4/15 编程问答 30 豆豆
生活随笔 收集整理的這篇文章主要介紹了 OpenCV isContinuous()连续存储的问题 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

OpenCV isContinuous()連續(xù)存儲的問題

尊重原創(chuàng),轉(zhuǎn)載請注明出處】http://blog.csdn.net/guyuealian/article/details/78614662

一、OpenCV isContinuous()函數(shù)

定義: bool cv::Mat::isContinuous() const
說明: ? ? ?報告矩陣是否連續(xù)。 ? ? ?如果矩陣元素在每行末尾連續(xù)存儲而沒有間隙,則方法返回true。 否則,它返回false。 顯然,對于1x1或1xN矩陣總是連續(xù)的。一般 用Mat :: create創(chuàng)建的矩陣總是連續(xù)的。 但是,如果使用Mat :: col,Mat :: diag等提取矩陣的一部分,或者為外部分配的數(shù)據(jù)構(gòu)造矩陣頭,則此類矩陣可能不再具有此屬性。 ? ? ?連續(xù)性標志存儲在Mat :: flags字段中,并在構(gòu)造矩陣標題時自動計算。 因此,連續(xù)性檢查是一個非常快的操作,雖然理論上可以這樣做:
// 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();//檢測內(nèi)存存儲連續(xù)性 }? ??這個isContinuous方法在很多OpenCV函數(shù)中都有使用。 重點在于元素操作(例如算術(shù)和邏輯操作,數(shù)學函數(shù),alpha?混合,顏色空間變換等)不依賴于圖像幾何。 因此,如果所有的輸入和輸出數(shù)組都是連續(xù)的,那么函數(shù)可以將它們處理為非常長的單行向量。 下面的例子說明了如何實現(xiàn)一個alpha混合(透明混合)函數(shù):
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%,特別是如果圖像相當小并且操作非常簡單。
? ? ?在這個函數(shù)中的另一個OpenCV習慣用法,調(diào)用目標數(shù)組的Mat :: create,除非它已經(jīng)具有適當?shù)拇笮『皖愋?#xff0c;否則分配目標數(shù)組。 而新分配的數(shù)組總是連續(xù)的,你仍然需要檢查目標數(shù)組,因為Mat :: create并不總是分配一個新的矩陣。 ? ? ?用Mat存儲一幅圖像時,若圖像在內(nèi)存中是連續(xù)存儲的(Mat對象的isContinuous == true),則可以將圖像的數(shù)據(jù)看成是一個一維數(shù)組,而data(uchar*)成員就是指向圖像數(shù)據(jù)的第一個字節(jié)的,因此可以用data指針訪問圖像的數(shù)據(jù),從而加速Mat圖像的訪問速度。

? ? ?一般經(jīng)過裁剪的Mat圖像,都不再連續(xù)了,如cv::Mat crop_img = src(rect);crop_img 是不連續(xù)的Mat圖像,如果想轉(zhuǎn)為連續(xù)的,最簡單的方法,就是將不連續(xù)的crop_img 重新clone()一份給新的Mat就是連續(xù)的了,如:

Mat src = imread("D:\\OpencvTest\\B1.jpg");//原始圖像是200*200 cv::imshow("src", src);printf("---src.isContinuous=%d", src.isContinuous()); printf("\n");//直接imread的Mat是連續(xù)的cv::Rect rect(1, 1, 100, 100);cv::Mat crop_img = src(rect);//裁剪后的圖像是不連續(xù)的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()后的圖像是連續(xù)的printf("---crop_img2.isContinuous=%d", crop_img2.isContinuous()); printf("\n"); 運行結(jié)果:顯然,裁剪后的Mat圖像不再連續(xù),而重新clone()一份后又連續(xù)了.




? ? ??

總結(jié)

以上是生活随笔為你收集整理的OpenCV isContinuous()连续存储的问题的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。