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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

访问Mat中每个像素的值

發(fā)布時(shí)間:2025/4/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 访问Mat中每个像素的值 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Color Reduce

還是使用經(jīng)典的Reduce Color的例子,即對(duì)圖像中的像素表達(dá)進(jìn)行量化。如常見(jiàn)的RGB24圖像有256×256×256中顏色,通過(guò)Reduce Color將每個(gè)通道的像素減少8倍至256/8=32種,則圖像只有32×32×32種顏色。假設(shè)量化減少的倍數(shù)是N,則代碼實(shí)現(xiàn)時(shí)就是簡(jiǎn)單的value/N*N,通常我們會(huì)再加上N/2以得到相鄰的N的倍數(shù)的中間值,最后圖像被量化為(256/N)×(256/N)×(256/N)種顏色。

方法零:.ptr和[]操作符

Mat最直接的訪問(wèn)方法是通過(guò).ptr<>函數(shù)得到一行的指針,并用[]操作符訪問(wèn)某一列的像素值。

[cpp]?view plaincopy
  • //?using?.ptr?and?[]??
  • void?colorReduce0(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ??????????????????data[i]=?data[i]/div*div?+?div/2;??
  • ????????????}????????????????????
  • ??????}??
  • }??

  • 方法一:.ptr和指針操作

    除了[]操作符,我們可以移動(dòng)指針*++的組合方法訪問(wèn)某一行中所有像素的值。

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++???
  • void?colorReduce1(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ?????????????????*data++=?*data/div*div?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法二:.ptr、指針操作和取模運(yùn)算

    方法二和方法一的訪問(wèn)方式相同,不同的是color reduce用模運(yùn)算代替整數(shù)除法

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++?and?modulo??
  • void?colorReduce2(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ??????????????????int?v=?*data;??
  • ??????????????????*data++=?v?-?v%div?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法三:.ptr、指針運(yùn)算和位運(yùn)算

    由于進(jìn)行量化的單元div通常是2的整次方,因此所有的乘法和除法都可以用位運(yùn)算表示。

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++?and?bitwise??
  • void?colorReduce3(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法四:指針運(yùn)算

    方法四和方法三量化處理的方法相同,不同的是用指針運(yùn)算代替*++操作。

    [cpp]?view plaincopy
  • //?direct?pointer?arithmetic??
  • void?colorReduce4(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????int?step=?image.step;?//?effective?width??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????//?get?the?pointer?to?the?image?buffer??
  • ??????uchar?*data=?image.data;??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ????????????*(data+i)=?*data&mask?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ????????????data+=?step;??//?next?line??
  • ??????}??
  • }??

  • 方法五:.ptr、*++、位運(yùn)算以及image.cols * image.channels()

    這種方法就是沒(méi)有計(jì)算nc,基本是個(gè)充數(shù)的方法。

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++?and?bitwise?with?image.cols?*?image.channels()??
  • void?colorReduce5(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<image.cols?*?image.channels();?i++)?{??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??
  • ?

    方法六:連續(xù)圖像

    Mat提供了isContinuous()函數(shù)用來(lái)查看Mat在內(nèi)存中是不是連續(xù)存儲(chǔ),如果是則圖片被存儲(chǔ)在一行中。

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++?and?bitwise?(continuous)??
  • void?colorReduce6(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?*?image.channels();?//?total?number?of?elements?per?line??
  • ??????if?(image.isContinuous())??{??
  • ??????????//?then?no?padded?pixels??
  • ??????????nc=?nc*nr;???
  • ??????????nr=?1;??//?it?is?now?a?1D?array??
  • ???????}??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法七:continuous+channels

    與方法六基本相同,也是充數(shù)的。

    [cpp]?view plaincopy
  • //?using?.ptr?and?*?++?and?bitwise?(continuous+channels)??
  • void?colorReduce7(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?;?//?number?of?columns??
  • ??????if?(image.isContinuous())??{??
  • ??????????//?then?no?padded?pixels??
  • ??????????nc=?nc*nr;???
  • ??????????nr=?1;??//?it?is?now?a?1D?array??
  • ???????}??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????*data++=?*data&mask?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法八:Mat _iterator

    真正有區(qū)別的方法來(lái)啦,用Mat提供的迭代器代替前面的[]操作符或指針,血統(tǒng)純正的官方方法~

    [cpp]?view plaincopy
  • //?using?Mat_?iterator???
  • void?colorReduce8(cv::Mat?&image,?int?div=64)?{??
  • ??????//?get?iterators??
  • ??????cv::Mat_<cv::Vec3b>::iterator?it=?image.begin<cv::Vec3b>();??
  • ??????cv::Mat_<cv::Vec3b>::iterator?itend=?image.end<cv::Vec3b>();??
  • ??????for?(?;?it!=?itend;?++it)?{??
  • ????????(*it)[0]=?(*it)[0]/div*div?+?div/2;??
  • ????????(*it)[1]=?(*it)[1]/div*div?+?div/2;??
  • ????????(*it)[2]=?(*it)[2]/div*div?+?div/2;??
  • ??????}??
  • }??
  • ?

    方法九:Mat_ iterator 和位運(yùn)算

    把方法八中的乘除法換成位運(yùn)算。

    [cpp]?view plaincopy
  • //?using?Mat_?iterator?and?bitwise??
  • void?colorReduce9(cv::Mat?&image,?int?div=64)?{??
  • ??????//?div?must?be?a?power?of?2??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????//?get?iterators??
  • ??????cv::Mat_<cv::Vec3b>::iterator?it=?image.begin<cv::Vec3b>();??
  • ??????cv::Mat_<cv::Vec3b>::iterator?itend=?image.end<cv::Vec3b>();??
  • ??????for?(?;?it!=?itend;?++it)?{??
  • ????????(*it)[0]=?(*it)[0]&mask?+?div/2;??
  • ????????(*it)[1]=?(*it)[1]&mask?+?div/2;??
  • ????????(*it)[2]=?(*it)[2]&mask?+?div/2;??
  • ??????}??
  • }??

  • 方法十:MatIterator_

    和方法八基本相同。

    [cpp]?view plaincopy
  • //?using?MatIterator_???
  • void?colorReduce10(cv::Mat?&image,?int?div=64)?{??
  • ??????cv::Mat_<cv::Vec3b>?cimage=?image;??
  • ??????cv::Mat_<cv::Vec3b>::iterator?it=cimage.begin();??
  • ??????cv::Mat_<cv::Vec3b>::iterator?itend=cimage.end();??
  • ??????for?(?;?it!=?itend;?it++)?{???
  • ????????(*it)[0]=?(*it)[0]/div*div?+?div/2;??
  • ????????(*it)[1]=?(*it)[1]/div*div?+?div/2;??
  • ????????(*it)[2]=?(*it)[2]/div*div?+?div/2;??
  • ??????}??
  • }??
  • ?

    方法十一:圖像坐標(biāo)

    [cpp]?view plaincopy
  • //?using?(j,i)??
  • void?colorReduce11(cv::Mat?&image,?int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols;?//?number?of?columns??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ??????????????????image.at<cv::Vec3b>(j,i)[0]=?????image.at<cv::Vec3b>(j,i)[0]/div*div?+?div/2;??
  • ??????????????????image.at<cv::Vec3b>(j,i)[1]=?????image.at<cv::Vec3b>(j,i)[1]/div*div?+?div/2;??
  • ??????????????????image.at<cv::Vec3b>(j,i)[2]=?????image.at<cv::Vec3b>(j,i)[2]/div*div?+?div/2;??
  • ????????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法十二:創(chuàng)建輸出圖像

    之前的方法都是直接修改原圖,方法十二新建了輸出圖像,主要用于后面的時(shí)間對(duì)比。

    [cpp]?view plaincopy
  • //?with?input/ouput?images??
  • void?colorReduce12(const?cv::Mat?&image,?//?input?image???
  • ?????????????????cv::Mat?&result,??????//?output?image??
  • ?????????????????int?div=64)?{??
  • ??????int?nr=?image.rows;?//?number?of?rows??
  • ??????int?nc=?image.cols?;?//?number?of?columns??
  • ??????//?allocate?output?image?if?necessary??
  • ??????result.create(image.rows,image.cols,image.type());??
  • ??????//?created?images?have?no?padded?pixels??
  • ??????nc=?nc*nr;???
  • ??????nr=?1;??//?it?is?now?a?1D?array??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????for?(int?j=0;?j<nr;?j++)?{??
  • ??????????uchar*?data=?result.ptr<uchar>(j);??
  • ??????????const?uchar*?idata=?image.ptr<uchar>(j);??
  • ??????????for?(int?i=0;?i<nc;?i++)?{??
  • ????????????*data++=?(*idata++)&mask?+?div/2;??
  • ????????????*data++=?(*idata++)&mask?+?div/2;??
  • ????????????*data++=?(*idata++)&mask?+?div/2;??
  • ??????????}?//?end?of?row???????????????????
  • ??????}??
  • }??

  • 方法十三:重載操作符

    Mat重載了+&等操作符,可以直接將兩個(gè)Scalar(B,G,R)數(shù)據(jù)進(jìn)行位運(yùn)算和數(shù)學(xué)運(yùn)算。

    [cpp]?view plaincopy
  • //?using?overloaded?operators??
  • void?colorReduce13(cv::Mat?&image,?int?div=64)?{??
  • ??????int?n=?static_cast<int>(log(static_cast<double>(div))/log(2.0));??
  • ??????//?mask?used?to?round?the?pixel?value??
  • ??????uchar?mask=?0xFF<<n;?//?e.g.?for?div=16,?mask=?0xF0??
  • ??????//?perform?color?reduction??
  • ??????image=(image&cv::Scalar(mask,mask,mask))+cv::Scalar(div/2,div/2,div/2);??
  • }??

  • 時(shí)間對(duì)比

    通過(guò)迭代二十次取平均時(shí)間,得到每種方法是運(yùn)算時(shí)間如下。

    可以看到,指針*++訪問(wèn)和位運(yùn)算是最快的方法;而不斷的計(jì)算image.cols*image.channles()花費(fèi)了大量重復(fù)的時(shí)間;另外迭代器訪問(wèn)雖然安全,但性能遠(yuǎn)低于指針運(yùn)算;通過(guò)圖像坐標(biāo)(j,i)訪問(wèn)時(shí)最慢的,使用重載操作符直接運(yùn)算效率最高。

    總結(jié)

    以上是生活随笔為你收集整理的访问Mat中每个像素的值的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

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

    主站蜘蛛池模板: 综合网伊人 | 欧美精品一级片 | 久久国产影视 | 亚州国产精品视频 | 国产亚洲精品久久久久久久 | 国产综合精品久久久久成人影 | 91高清视频| 国产精品999在线观看 | 国产天堂视频 | 久久精品| 动漫精品一区 | 黄色一级片毛片 | 少妇又色又爽又黄的视频 | 91亚洲一区| 国产精品大屁股白浆一区 | 日日噜噜夜夜狠狠久久波多野 | 91av小视频| 在线免费小视频 | 婷婷六月在线 | 极品美女扒开粉嫩小泬 | 精品小视频在线观看 | 亚洲第一精品在线观看 | 一个人在线观看免费视频www | 亚洲好骚综合 | 撒尿free性hd | 337p粉嫩色噜噜噜大肥臀 | 男人天堂网址 | 手机看片1024欧美 | 国精产品一区一区三区免费视频 | 综合在线观看 | 一级美女大片 | 伦理片中文字幕 | 国产宾馆实践打屁股91 | 国产情侣在线视频 | 影音先锋激情 | 丰满人妻一区二区三区53视频 | a亚洲天堂 | 538精品一线 | a一级免费视频 | 欧美嫩交| 国产97视频 | xxxxwwww在线观看| 天天综合干 | 免费视频www在线观看网站 | 美女色网站 | av剧情在线| 天堂a√在线 | 欧美美女一区二区 | 欧美特级黄色大片 | 蜜臀久久99精品久久久久久 | 很黄很色的视频 | 男人天堂视频在线 | 精品一区免费 | 欧美亚洲国产视频 | 女人性高潮视频 | a级欧美| 国产精品一区二区久久 | 中文字幕亚洲一区 | 国产精品一区二区三区免费观看 | 阿v免费在线观看 | 粗喘呻吟撞击猛烈疯狂 | 欧美日韩亚 | 久在线观看| 色网址在线观看 | 一区二区三区四区在线免费观看 | 欧美综合另类 | 亚洲无限看 | 四虎永久在线精品免费网址 | 亚洲一区中文字幕永久在线 | 捆绑无遮挡打光屁股调教女仆 | 先锋资源在线视频 | 超碰人人爱人人 | 亚洲插插插| 51吃瓜网今日吃瓜 | av午夜天堂 | 好吊一区二区三区视频 | 国产另类专区 | 国产老头户外野战xxxxx | 狠狠干免费视频 | 污版视频在线观看 | 国产精品成人aaaaa网站 | 伊人影院综合 | 欧美精品久久99 | 精品国产99久久久久久宅男i | 91香蕉一区二区三区在线观看 | 在线一区观看 | 青娱乐免费在线视频 | 国产男女猛烈无遮挡 | 美女伦理水蜜桃4 | 国产看真人毛片爱做a片 | 伊人网五月天 | 综合性色| 操极品女神 | 久久无码人妻丰满熟妇区毛片 | 91香草视频 | 欧美一区二区三区公司 | 激情成人av| 深爱激情综合网 | 制服.丝袜.亚洲.中文.综合懂色 |