SlideShare ist ein Scribd-Unternehmen logo
1 von 16
Downloaden Sie, um offline zu lesen
POPCNTによるハミング距離
計算とステレオ対応への応用
      名古屋工業大学
          福嶋慶繁
  Twitter: @fukushima1981
POPCNT
• POPCNT:
  – データの非ゼロのビット数を数える
  – Population countの略
• VC,GCCでは下記関数で,値が確保可能
  – Int val = _mm_popcnt_u32(unsigned long)
• SSE4.2から対応
  – 一昔前のCore i7よりも新しいCPUのみ対応
なんの役に立つの?



ハミング距離が計算可能
ハミング距離(Hamming Distance)
• データ中のビットの違いの数
• 例 AとBのハミング距離は?
 – A:00100101
 – B:00101011
 – 3つ異なるので3

 – L0ノルムに似た距離尺度
popcnt使い方
• popcnt:
   – ビット中の非ゼロの数を高速に数えてくれる
• ハミング距離:
   – 2つのビット列のうち異なるビットの数
• つまり,2つのビット列の異なり具合を表すビット列をpopcntすれば即座
  にハミング距離が求まる.
   – それはAとBの排他的論理和で表現可能
   – 2つの値が同じなら0違うなら1を出力する論理演算
   – A XOR B, c,c++では, A^B;


       popcnt(A^B);
これだけでハミング距離が測定できる!
POPCNTによるハミング距離
• 入力データ
  – A:00100101
  – B:00101011
• 排他的論理和
  – A^B:00001110
• POPCNT
  – popcnt(00001110)=3

• AとBのハミング距離は3!
例題:ステレオマッチング
• ステレオマッチング
 – 左右の画素の一致度を図り,最も一致した画素
   を元に奥行きを計算する
 – 単純な距離尺度:絶対誤差,二乗誤差
  • abs(L-R):SAD
  • (L-R)^2 :SSD
 – ハミング距離を使う距離尺度もある
  • CENSUS変換
CENSUS Transform (1/2)
• 画素中に適当なウィンドウを張り,中心の画素と周
  辺の画素との大小関係をバイナリベクトルに変換す
  る変換
• 中心<周辺 ? 1 : 0
• ベクトル長はウィンドウの大きさに依存
CENSUS Transform (2/2)
• 8bitのCENSUS変換(つまり窓の面積が,中心を除く8画素)な
  ら画像として表現も可能
• それ以上の窓サイズになると桁があふれて画像としては可
  視化不可能




      入力画像            CENSUS変換画像
CENSUS変換によるステレオマッチング
1. 左右の画像(Iml,Imr)をCENSUS変換した画像を作成:
   (Iml,Imr)→(Imlcensus,Imrcensus )
2. 右の変換画像をある視差dだけシフト
     Imrcensus (x)→   Imrcensus (x-d)
3. シフトした右CENSUS画像と左CENSUS画像のハミング
   距離を計算
   distance(d)= Hamming(Imlcensus (x) , Imrcensus (x-d))

4. もっともハミング距離が小さかった視差値をその画素
   の視差として採用
    disp = argmind distance(d)
例題:ステレオマッチング(入力)




 Left Image          Right Image

  左右ともども9x1の窓で全体をCENSUS変換
例題:ステレオマッチング(出力)




 SAD:                    CENSUS:
 95 msec                 107 msec
SADという非常に簡単な絶対値差分と比べて速度面はほとんど変わらない
CENSUS変換の利点
• 輝度値を直接比較しないので照明変動につ
  よい
 – 中央との相対関係をもとに比較
• ノイズに強い
 – バイナリの値を比較するので,微小なノイズの影
   響が少ない
• 模様が少ない領域での対応付けが安定する
 – 中心との差分→微分のような効果があるためエッ
   ジ(模様)を強調する効果
Sample code
                                    Stereo Matching のサンプルコード:詳細は次ページ
void calcHammingDistance8u(Mat& src1, Mat& src2, Mat& dest)
{
                                                                                    if(dest.empty())dest.create(src1.size(),CV_8U);
                                                                                    int i,j;
                                                                                    uchar* s1 = src1.ptr<uchar>(0);
                                                                                    uchar* s2 = src2.ptr<uchar>(0);
                                                                                    uchar* d = dest.ptr<uchar>(0);
                                                                                    int count=0;
                                                                                    const int hstep = src1.cols/16;
                                                                                    const int rad= src1.cols- hstep*16;

                                                                                    for(j=src1.rows;j--;)
                                                                                    {
                                                                                                                                                                           //base
                                                                                                                                                                           for(i=src1.cols;i--;)
                                                                                                                                                                           {
                                                                                                                                                                                                                              *d = _mm_popcnt_u32((unsigned int)(*s1^*s2));
                                                                                                                                                                                                                              s1++;s2++,d++;
                                                                                                                                                                           }

                                                                                    }
}
void censusTrans8u_8x1(Mat& src, Mat& dest)
{
                                                                                    if(dest.empty())dest.create(src.size(),CV_8U);
                                                                                    const int r=4;
                                                                                    const int r2=2*r;
                                                                                    Mat im;copyMakeBorder(src,im,0,0,r,r,cv::BORDER_REPLICATE);

                                                                                    int i,j,n;

                                                                                    uchar* s = im.ptr<uchar>(0);s+=r;
                                                                                    uchar* d = dest.ptr<uchar>(0);
                                                                                    for(j=0;j<src.rows;j++)
                                                                                    {
                                                                                                                                                                           for(i=0;i<src.cols;i++)
                                                                                                                                                                           {
                                                                                                                                                                                                                              uchar val = 0;//init value
                                                                                                                                                                                                                              uchar* ss=s-r;
                                                                                                                                                                                                                              for(n = 0;n<r;n++)
                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                              //if (*ss<*s)val|=1;
                                                                                                                                                                                                                                                                              val = (*ss<*s) ? val|1 : val;
                                                                                                                                                                                                                                                                              ss++;
                                                                                                                                                                                                                                                                              val <<=1;
                                                                                                                                                                                                                              }
                                                                                                                                                                                                                              ss++;//skip r=0
                                                                                                                                                                                                                              for(n = 0;n<r;n++)
                                                                                                                                                                                                                              {
                                                                                                                                                                                                                                                                              val = (*ss<*s) ? val|1 : val;
                                                                                                                                                                                                                                                                              ss++;
                                                                                                                                                                                                                                                                              val <<=1;
                                                                                                                                                                                                                              }
                                                                                                                                                                                                                              *d=val;
                                                                                                                                                                                                                              d++;
                                                                                                                                                                                                                              s++;
                                                                                                                                                                           }
                                                                                                                                                                           s+=r2;
                                                                                    }
}
void shiftImage8u(Mat& src, Mat& dest, const int shift)
{
                                                                                    if(dest.empty())dest.create(src.size(),CV_8U);

                                                                                    if(shift>=0)
                                                                                    {
                                                                                                                                                                           const int step = src.cols;
                                                                                                                                                                           uchar* s = src.ptr<uchar>(0);
                                                                                                                                                                           uchar* d = dest.ptr<uchar>(0);
                                                                                                                                                                           int j;j=0;
                                                                                                                                                                           for(;j<src.rows;j++)
                                                                                                                                                                           {
                                                                                                                                                                                                                              const uchar v = s[0];
                                                                                                                                                                                                                              memset(d,v,shift);
                                                                                                                                                                                                                              memcpy(d+shift,s,step-shift);
                                                                                                                                                                                                                              s+=step;d+=step;
                                                                                                                                                                           }
                                                                                    }
                                                                                    else
                                                                                    {
                                                                                                                                                                           const int step = src.cols;
                                                                                                                                                                           uchar* s = src.ptr<uchar>(0);
                                                                                                                                                                           uchar* d = dest.ptr<uchar>(0);
                                                                                                                                                                           int j;j=0;
                                                                                                                                                                           for(;j<src.rows;j++)
                                                                                                                                                                           {
                                                                                                                                                                                                                              const uchar v = s[step-1];
                                                                                                                                                                                                                              memcpy(d,s+shift,step-shift);
                                                                                                                                                                                                                              memset(d+step-shift,v,shift);
                                                                                                                                                                                                                              s+=step;d+=step;
                                                                                                                                                                           }
                                                                                    }
}
void stereoCensus8x1(Mat& leftim, Mat& rightim, Mat& dest, int minDisparity, int range, int r)
{
                                                                                     if(dest.empty())dest.create(leftim.size(),CV_8U);
                                                                                     Mat lim,rim;
                                                                                     if(leftim.channels()==3)cvtColor(leftim,lim,CV_BGR2GRAY);
                                                                                     else lim=leftim;
                                                                                     if(rightim.channels()==3)cvtColor(rightim,rim,CV_BGR2GRAY);
                                                                                     else rim=rightim;

                                                                                    Mat limCensus,rimCensus;
                                                                                    censusTrans8u_8x1(lim,limCensus);
                                                                                    censusTrans8u_8x1(rim,rimCensus);
                                                                                    Mat rwarp;
                                                                                    Mat distance;

                                                                                    vector<Mat> dsv(range);
                                                                                    for(int i=0;i<range;i++)
                                                                                    {
                                                                                                                                                                           shiftImage8u(rimCensus , rwarp,minDisparity+i);
                                                                                                                                                                           calcHammingDistance8u(limCensus,rwarp,distance);
                                                                                                                                                                           blur(distance,dsv[i],Size(2*r+1,2*r+1));
                                                                                    }

                                                                                    Size size = dest.size();
                                                                                    Mat cost = Mat::ones(size,VOLUME_TYPE)*255;
                                                                                    Mat mask;
                                                                                    const int imsize = size.area();
                                                                                    for(int i=0;i<range;i++)
                                                                                    {
                                                                                                                                                                           Mat pcost;
                                                                                                                                                                           cost.copyTo(pcost);
                                                                                                                                                                           min(pcost,dsv[i],cost);
                                                                                                                                                                           compare(pcost,cost,mask,cv::CMP_NE);
                                                                                                                                                                           dest.setTo(i+minDisparity,mask);
                                                                                    }
}
                                                                                    void stereoSAD(Mat& leftim, Mat& rightim, Mat& dest, int minDisparity, int range, int r)
{
                                                                                    if(dest.empty())dest.create(leftim.size(),CV_8U);
                                                                                    Mat lim,rim;
                                                                                    if(leftim.channels()==3)cvtColor(leftim,lim,CV_BGR2GRAY);
                                                                                    else lim=leftim;
                                                                                    if(rightim.channels()==3)cvtColor(rightim,rim,CV_BGR2GRAY);
                                                                                    else rim=rightim;

                                                                                    Mat rwarp;
                                                                                    Mat distance;

                                                                                    vector<Mat> dsv(range);
                                                                                    for(int i=0;i<range;i++)
                                                                                    {
                                                                                                                                                                           shiftImage8u(rim , rwarp,minDisparity+i);
                                                                                                                                                                           absdiff(lim,rwarp,distance);
                                                                                                                                                                           blur(distance,dsv[i],Size(2*r+1,2*r+1));
                                                                                    }

                                                                                    Size size = dest.size();
                                                                                    Mat cost = Mat::ones(size,VOLUME_TYPE)*255;
                                                                                    Mat mask;
                                                                                    const int imsize = size.area();
                                                                                    for(int i=0;i<range;i++)
                                                                                    {
                                                                                                                                                                           Mat pcost;
                                                                                                                                                                           cost.copyTo(pcost);
                                                                                                                                                                           min(pcost,dsv[i],cost);
                                                                                                                                                                           compare(pcost,cost,mask,cv::CMP_NE);
                                                                                                                                                                           dest.setTo(i+minDisparity,mask);
                                                                                    }
}
ハミング距離サンプル
  画像Aと画像Bの各画素のハミング距離計測のサンプル(OpenCVによる実装)

void calcHammingDistance8u(Mat& src1, Mat& src2, Mat& dest)
{
          if(dest.empty())dest.create(src1.size(),CV_8U);
          int i,j;
          uchar* s1 = src1.ptr<uchar>(0);
          uchar* s2 = src2.ptr<uchar>(0);
          uchar* d = dest.ptr<uchar>(0);
          for(j=src1.rows;j--;)
          {
                    for(i=src1.cols;i--;)
                    {
                                *d = _mm_popcnt_u32((unsigned int)(*s1^*s2));
                                s1++;s2++,d++;
                    }
          }
}
画像のCENSUS変換サンプル
9x1の横長の窓でのCENSUS変換.条件を満たしたら1とのbit orを取って,
次に備えてbit shiftしているだけ
 void censusTrans8u_8x1(Mat& src, Mat& dest)
 {
                   if(dest.empty())dest.create(src.size(),CV_8U);
                   const int r=4;
                   const int r2=2*r;
                   Mat im;copyMakeBorder(src,im,0,0,r,r,cv::BORDER_REPLICATE);
                   int i,j,n;
                   uchar* s = im.ptr<uchar>(0);s+=r;
                   uchar* d = dest.ptr<uchar>(0);
                   for(j=0;j<src.rows;j++)
                   {
                                        for(i=0;i<src.cols;i++)
                                        {
                                                              uchar val = 0;//init value
                                                              uchar* ss=s-r;
                                                              for(n = 0;n<r;n++)
                                                              {
                                                                                    val = (*ss<*s) ? val|1 : val;
                                                                                    ss++;
                                                                                    val <<=1;
                                                              }
                                                              ss++;//skip r=0
                                                              for(n = 0;n<r;n++)
                                                              {
                                                                                    val = (*ss<*s) ? val|1 : val;
                                                                                    ss++;
                                                                                    val <<=1;
                                                              }
                                                              *d=val;
                                                              d++;
                                                              s++;
                                        }
                                        s+=r2;
                   }
 }

Weitere ähnliche Inhalte

Was ist angesagt?

画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
MPRG_Chubu_University
 
ガイデットフィルタとその周辺
ガイデットフィルタとその周辺ガイデットフィルタとその周辺
ガイデットフィルタとその周辺
Norishige Fukushima
 

Was ist angesagt? (20)

Semantic segmentation
Semantic segmentationSemantic segmentation
Semantic segmentation
 
【メタサーベイ】Neural Fields
【メタサーベイ】Neural Fields【メタサーベイ】Neural Fields
【メタサーベイ】Neural Fields
 
ORB-SLAMの手法解説
ORB-SLAMの手法解説ORB-SLAMの手法解説
ORB-SLAMの手法解説
 
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
 
PCL
PCLPCL
PCL
 
論文紹介"DynamicFusion: Reconstruction and Tracking of Non-­‐rigid Scenes in Real...
論文紹介"DynamicFusion: Reconstruction and Tracking of Non-­‐rigid Scenes in Real...論文紹介"DynamicFusion: Reconstruction and Tracking of Non-­‐rigid Scenes in Real...
論文紹介"DynamicFusion: Reconstruction and Tracking of Non-­‐rigid Scenes in Real...
 
SSII2021 [TS1] Visual SLAM ~カメラ幾何の基礎から最近の技術動向まで~
SSII2021 [TS1] Visual SLAM ~カメラ幾何の基礎から最近の技術動向まで~SSII2021 [TS1] Visual SLAM ~カメラ幾何の基礎から最近の技術動向まで~
SSII2021 [TS1] Visual SLAM ~カメラ幾何の基礎から最近の技術動向まで~
 
画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
画像局所特徴量と特定物体認識 - SIFTと最近のアプローチ -
 
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
SSII2019TS: 実践カメラキャリブレーション ~カメラを用いた実世界計測の基礎と応用~
 
Jetson TK1でSemi-Global Matching
Jetson TK1でSemi-Global MatchingJetson TK1でSemi-Global Matching
Jetson TK1でSemi-Global Matching
 
近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer近年のHierarchical Vision Transformer
近年のHierarchical Vision Transformer
 
ガイデットフィルタとその周辺
ガイデットフィルタとその周辺ガイデットフィルタとその周辺
ガイデットフィルタとその周辺
 
semantic segmentation サーベイ
semantic segmentation サーベイsemantic segmentation サーベイ
semantic segmentation サーベイ
 
コンピューテーショナルフォトグラフィ
コンピューテーショナルフォトグラフィコンピューテーショナルフォトグラフィ
コンピューテーショナルフォトグラフィ
 
3D CNNによる人物行動認識の動向
3D CNNによる人物行動認識の動向3D CNNによる人物行動認識の動向
3D CNNによる人物行動認識の動向
 
NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門NumPyが物足りない人へのCython入門
NumPyが物足りない人へのCython入門
 
SSII2021 [OS3-01] 設備や環境の高品質計測点群取得と自動モデル化技術
SSII2021 [OS3-01] 設備や環境の高品質計測点群取得と自動モデル化技術SSII2021 [OS3-01] 設備や環境の高品質計測点群取得と自動モデル化技術
SSII2021 [OS3-01] 設備や環境の高品質計測点群取得と自動モデル化技術
 
Open3DでSLAM入門 PyCon Kyushu 2018
Open3DでSLAM入門 PyCon Kyushu 2018Open3DでSLAM入門 PyCon Kyushu 2018
Open3DでSLAM入門 PyCon Kyushu 2018
 
SSII2019企画: 点群深層学習の研究動向
SSII2019企画: 点群深層学習の研究動向SSII2019企画: 点群深層学習の研究動向
SSII2019企画: 点群深層学習の研究動向
 
【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習【メタサーベイ】数式ドリブン教師あり学習
【メタサーベイ】数式ドリブン教師あり学習
 

Andere mochten auch

A x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequencesA x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequences
Takeshi Yamamuro
 
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみたGPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
Ryo Sakamoto
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
MITSUNARI Shigeo
 

Andere mochten auch (20)

x86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNTx86x64 SSE4.2 POPCNT
x86x64 SSE4.2 POPCNT
 
明日使えないすごいビット演算
明日使えないすごいビット演算明日使えないすごいビット演算
明日使えないすごいビット演算
 
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
AVX2時代の正規表現マッチング 〜半群でぐんぐん!〜
 
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
GPUが100倍速いという神話をぶち殺せたらいいな ver.2013
 
最適化超入門
最適化超入門最適化超入門
最適化超入門
 
マルチコアを用いた画像処理
マルチコアを用いた画像処理マルチコアを用いた画像処理
マルチコアを用いた画像処理
 
X86opti01 nothingcosmos
X86opti01 nothingcosmosX86opti01 nothingcosmos
X86opti01 nothingcosmos
 
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないこと画像処理ライブラリ OpenCV で 出来ること・出来ないこと
画像処理ライブラリ OpenCV で 出来ること・出来ないこと
 
A x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequencesA x86-optimized rank&select dictionary for bit sequences
A x86-optimized rank&select dictionary for bit sequences
 
はじパタLT3
はじパタLT3はじパタLT3
はじパタLT3
 
GPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみたGPGPU deいろんな問題解いてみた
GPGPU deいろんな問題解いてみた
 
Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介Haswellサーベイと有限体クラスの紹介
Haswellサーベイと有限体クラスの紹介
 
Libjpeg turboの使い方
Libjpeg turboの使い方Libjpeg turboの使い方
Libjpeg turboの使い方
 
Stereo vision
Stereo visionStereo vision
Stereo vision
 
Comparison between Blur Transfer and Blur Re-Generation in Depth Image Based ...
Comparison between Blur Transfer and Blur Re-Generation in Depth Image Based ...Comparison between Blur Transfer and Blur Re-Generation in Depth Image Based ...
Comparison between Blur Transfer and Blur Re-Generation in Depth Image Based ...
 
OpenCVの拡張ユーティリティ関数群
OpenCVの拡張ユーティリティ関数群OpenCVの拡張ユーティリティ関数群
OpenCVの拡張ユーティリティ関数群
 
WebP入門
WebP入門WebP入門
WebP入門
 
Polymerやってみた
PolymerやってみたPolymerやってみた
Polymerやってみた
 
AngularJSでデータビジュアライゼーションがしたい
AngularJSでデータビジュアライゼーションがしたいAngularJSでデータビジュアライゼーションがしたい
AngularJSでデータビジュアライゼーションがしたい
 
Angular 2のRenderer
Angular 2のRendererAngular 2のRenderer
Angular 2のRenderer
 

Ähnlich wie Popcntによるハミング距離計算

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
yak1ex
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
egtra
 
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
Hiro H.
 
C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1
sunaemon
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
えぴ 福田
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
Norishige Fukushima
 
Usp友の会勉強会、ジャクソン構造図の巻(前編)
Usp友の会勉強会、ジャクソン構造図の巻(前編)Usp友の会勉強会、ジャクソン構造図の巻(前編)
Usp友の会勉強会、ジャクソン構造図の巻(前編)
umidori
 

Ähnlich wie Popcntによるハミング距離計算 (18)

C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
“Symbolic bounds analysis of pointers, array indices, and accessed memory reg...
 
C++0x in programming competition
C++0x in programming competitionC++0x in programming competition
C++0x in programming competition
 
競技プログラミングのためのC++入門
競技プログラミングのためのC++入門競技プログラミングのためのC++入門
競技プログラミングのためのC++入門
 
Brief introduction of Boost.ICL
Brief introduction of Boost.ICLBrief introduction of Boost.ICL
Brief introduction of Boost.ICL
 
C++11概要 ライブラリ編
C++11概要 ライブラリ編C++11概要 ライブラリ編
C++11概要 ライブラリ編
 
初めてのSTL
初めてのSTL初めてのSTL
初めてのSTL
 
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
2011.12.10 関数型都市忘年会 発表資料「最近書いた、関数型言語と関連する?C++プログラムの紹介」
 
X hago2 shortcoding 20110827
X hago2 shortcoding 20110827X hago2 shortcoding 20110827
X hago2 shortcoding 20110827
 
C++ lecture-1
C++ lecture-1C++ lecture-1
C++ lecture-1
 
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング(Ruby使いのための)Scalaで学ぶ関数型プログラミング
(Ruby使いのための)Scalaで学ぶ関数型プログラミング
 
C++によるソート入門
C++によるソート入門C++によるソート入門
C++によるソート入門
 
ぱっと見でわかるC++11
ぱっと見でわかるC++11ぱっと見でわかるC++11
ぱっと見でわかるC++11
 
組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門組み込み関数(intrinsic)によるSIMD入門
組み込み関数(intrinsic)によるSIMD入門
 
Processing資料(6) 様々な図形
Processing資料(6) 様々な図形Processing資料(6) 様々な図形
Processing資料(6) 様々な図形
 
最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)最新C++事情 C++14-C++20 (2018年10月)
最新C++事情 C++14-C++20 (2018年10月)
 
Usp友の会勉強会、ジャクソン構造図の巻(前編)
Usp友の会勉強会、ジャクソン構造図の巻(前編)Usp友の会勉強会、ジャクソン構造図の巻(前編)
Usp友の会勉強会、ジャクソン構造図の巻(前編)
 
人工無脳バトル 1st STEP 回答と解説
人工無脳バトル 1st STEP 回答と解説人工無脳バトル 1st STEP 回答と解説
人工無脳バトル 1st STEP 回答と解説
 

Mehr von Norishige Fukushima

複数台のKinectV2の使い方
複数台のKinectV2の使い方複数台のKinectV2の使い方
複数台のKinectV2の使い方
Norishige Fukushima
 
コンピュテーショナルフォトグラフティの基礎
コンピュテーショナルフォトグラフティの基礎コンピュテーショナルフォトグラフティの基礎
コンピュテーショナルフォトグラフティの基礎
Norishige Fukushima
 

Mehr von Norishige Fukushima (9)

画像処理の高性能計算
画像処理の高性能計算画像処理の高性能計算
画像処理の高性能計算
 
計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~計算スケジューリングの効果~もし,Halideがなかったら?~
計算スケジューリングの効果~もし,Halideがなかったら?~
 
多チャンネルバイラテラルフィルタの高速化
多チャンネルバイラテラルフィルタの高速化多チャンネルバイラテラルフィルタの高速化
多チャンネルバイラテラルフィルタの高速化
 
計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング計算機アーキテクチャを考慮した高能率画像処理プログラミング
計算機アーキテクチャを考慮した高能率画像処理プログラミング
 
3次元計測とフィルタリング
3次元計測とフィルタリング3次元計測とフィルタリング
3次元計測とフィルタリング
 
デプスセンサとその応用
デプスセンサとその応用デプスセンサとその応用
デプスセンサとその応用
 
複数台のKinectV2の使い方
複数台のKinectV2の使い方複数台のKinectV2の使い方
複数台のKinectV2の使い方
 
Non-essentiality of Correlation between Image and Depth Map in Free Viewpoin...
Non-essentiality of Correlation between Image and Depth Map in Free Viewpoin...Non-essentiality of Correlation between Image and Depth Map in Free Viewpoin...
Non-essentiality of Correlation between Image and Depth Map in Free Viewpoin...
 
コンピュテーショナルフォトグラフティの基礎
コンピュテーショナルフォトグラフティの基礎コンピュテーショナルフォトグラフティの基礎
コンピュテーショナルフォトグラフティの基礎
 

Kürzlich hochgeladen

Kürzlich hochgeladen (7)

Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その22024/04/26の勉強会で発表されたものです。
 
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
NewSQLの可用性構成パターン(OCHaCafe Season 8 #4 発表資料)
 
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
Amazon SES を勉強してみる その32024/04/26の勉強会で発表されたものです。
 
新人研修 後半 2024/04/26の勉強会で発表されたものです。
新人研修 後半        2024/04/26の勉強会で発表されたものです。新人研修 後半        2024/04/26の勉強会で発表されたものです。
新人研修 後半 2024/04/26の勉強会で発表されたものです。
 
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
LoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイスLoRaWANスマート距離検出センサー  DS20L  カタログ  LiDARデバイス
LoRaWANスマート距離検出センサー DS20L カタログ LiDARデバイス
 
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアルLoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
LoRaWAN スマート距離検出デバイスDS20L日本語マニュアル
 
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
業務で生成AIを活用したい人のための生成AI入門講座(社外公開版:キンドリルジャパン社内勉強会:2024年4月発表)
 

Popcntによるハミング距離計算

  • 1. POPCNTによるハミング距離 計算とステレオ対応への応用 名古屋工業大学 福嶋慶繁 Twitter: @fukushima1981
  • 2. POPCNT • POPCNT: – データの非ゼロのビット数を数える – Population countの略 • VC,GCCでは下記関数で,値が確保可能 – Int val = _mm_popcnt_u32(unsigned long) • SSE4.2から対応 – 一昔前のCore i7よりも新しいCPUのみ対応
  • 4. ハミング距離(Hamming Distance) • データ中のビットの違いの数 • 例 AとBのハミング距離は? – A:00100101 – B:00101011 – 3つ異なるので3 – L0ノルムに似た距離尺度
  • 5. popcnt使い方 • popcnt: – ビット中の非ゼロの数を高速に数えてくれる • ハミング距離: – 2つのビット列のうち異なるビットの数 • つまり,2つのビット列の異なり具合を表すビット列をpopcntすれば即座 にハミング距離が求まる. – それはAとBの排他的論理和で表現可能 – 2つの値が同じなら0違うなら1を出力する論理演算 – A XOR B, c,c++では, A^B; popcnt(A^B); これだけでハミング距離が測定できる!
  • 6. POPCNTによるハミング距離 • 入力データ – A:00100101 – B:00101011 • 排他的論理和 – A^B:00001110 • POPCNT – popcnt(00001110)=3 • AとBのハミング距離は3!
  • 7. 例題:ステレオマッチング • ステレオマッチング – 左右の画素の一致度を図り,最も一致した画素 を元に奥行きを計算する – 単純な距離尺度:絶対誤差,二乗誤差 • abs(L-R):SAD • (L-R)^2 :SSD – ハミング距離を使う距離尺度もある • CENSUS変換
  • 8. CENSUS Transform (1/2) • 画素中に適当なウィンドウを張り,中心の画素と周 辺の画素との大小関係をバイナリベクトルに変換す る変換 • 中心<周辺 ? 1 : 0 • ベクトル長はウィンドウの大きさに依存
  • 9. CENSUS Transform (2/2) • 8bitのCENSUS変換(つまり窓の面積が,中心を除く8画素)な ら画像として表現も可能 • それ以上の窓サイズになると桁があふれて画像としては可 視化不可能 入力画像 CENSUS変換画像
  • 10. CENSUS変換によるステレオマッチング 1. 左右の画像(Iml,Imr)をCENSUS変換した画像を作成: (Iml,Imr)→(Imlcensus,Imrcensus ) 2. 右の変換画像をある視差dだけシフト Imrcensus (x)→ Imrcensus (x-d) 3. シフトした右CENSUS画像と左CENSUS画像のハミング 距離を計算 distance(d)= Hamming(Imlcensus (x) , Imrcensus (x-d)) 4. もっともハミング距離が小さかった視差値をその画素 の視差として採用 disp = argmind distance(d)
  • 11. 例題:ステレオマッチング(入力) Left Image Right Image 左右ともども9x1の窓で全体をCENSUS変換
  • 12. 例題:ステレオマッチング(出力) SAD: CENSUS: 95 msec 107 msec SADという非常に簡単な絶対値差分と比べて速度面はほとんど変わらない
  • 13. CENSUS変換の利点 • 輝度値を直接比較しないので照明変動につ よい – 中央との相対関係をもとに比較 • ノイズに強い – バイナリの値を比較するので,微小なノイズの影 響が少ない • 模様が少ない領域での対応付けが安定する – 中心との差分→微分のような効果があるためエッ ジ(模様)を強調する効果
  • 14. Sample code Stereo Matching のサンプルコード:詳細は次ページ void calcHammingDistance8u(Mat& src1, Mat& src2, Mat& dest) { if(dest.empty())dest.create(src1.size(),CV_8U); int i,j; uchar* s1 = src1.ptr<uchar>(0); uchar* s2 = src2.ptr<uchar>(0); uchar* d = dest.ptr<uchar>(0); int count=0; const int hstep = src1.cols/16; const int rad= src1.cols- hstep*16; for(j=src1.rows;j--;) { //base for(i=src1.cols;i--;) { *d = _mm_popcnt_u32((unsigned int)(*s1^*s2)); s1++;s2++,d++; } } } void censusTrans8u_8x1(Mat& src, Mat& dest) { if(dest.empty())dest.create(src.size(),CV_8U); const int r=4; const int r2=2*r; Mat im;copyMakeBorder(src,im,0,0,r,r,cv::BORDER_REPLICATE); int i,j,n; uchar* s = im.ptr<uchar>(0);s+=r; uchar* d = dest.ptr<uchar>(0); for(j=0;j<src.rows;j++) { for(i=0;i<src.cols;i++) { uchar val = 0;//init value uchar* ss=s-r; for(n = 0;n<r;n++) { //if (*ss<*s)val|=1; val = (*ss<*s) ? val|1 : val; ss++; val <<=1; } ss++;//skip r=0 for(n = 0;n<r;n++) { val = (*ss<*s) ? val|1 : val; ss++; val <<=1; } *d=val; d++; s++; } s+=r2; } } void shiftImage8u(Mat& src, Mat& dest, const int shift) { if(dest.empty())dest.create(src.size(),CV_8U); if(shift>=0) { const int step = src.cols; uchar* s = src.ptr<uchar>(0); uchar* d = dest.ptr<uchar>(0); int j;j=0; for(;j<src.rows;j++) { const uchar v = s[0]; memset(d,v,shift); memcpy(d+shift,s,step-shift); s+=step;d+=step; } } else { const int step = src.cols; uchar* s = src.ptr<uchar>(0); uchar* d = dest.ptr<uchar>(0); int j;j=0; for(;j<src.rows;j++) { const uchar v = s[step-1]; memcpy(d,s+shift,step-shift); memset(d+step-shift,v,shift); s+=step;d+=step; } } } void stereoCensus8x1(Mat& leftim, Mat& rightim, Mat& dest, int minDisparity, int range, int r) { if(dest.empty())dest.create(leftim.size(),CV_8U); Mat lim,rim; if(leftim.channels()==3)cvtColor(leftim,lim,CV_BGR2GRAY); else lim=leftim; if(rightim.channels()==3)cvtColor(rightim,rim,CV_BGR2GRAY); else rim=rightim; Mat limCensus,rimCensus; censusTrans8u_8x1(lim,limCensus); censusTrans8u_8x1(rim,rimCensus); Mat rwarp; Mat distance; vector<Mat> dsv(range); for(int i=0;i<range;i++) { shiftImage8u(rimCensus , rwarp,minDisparity+i); calcHammingDistance8u(limCensus,rwarp,distance); blur(distance,dsv[i],Size(2*r+1,2*r+1)); } Size size = dest.size(); Mat cost = Mat::ones(size,VOLUME_TYPE)*255; Mat mask; const int imsize = size.area(); for(int i=0;i<range;i++) { Mat pcost; cost.copyTo(pcost); min(pcost,dsv[i],cost); compare(pcost,cost,mask,cv::CMP_NE); dest.setTo(i+minDisparity,mask); } } void stereoSAD(Mat& leftim, Mat& rightim, Mat& dest, int minDisparity, int range, int r) { if(dest.empty())dest.create(leftim.size(),CV_8U); Mat lim,rim; if(leftim.channels()==3)cvtColor(leftim,lim,CV_BGR2GRAY); else lim=leftim; if(rightim.channels()==3)cvtColor(rightim,rim,CV_BGR2GRAY); else rim=rightim; Mat rwarp; Mat distance; vector<Mat> dsv(range); for(int i=0;i<range;i++) { shiftImage8u(rim , rwarp,minDisparity+i); absdiff(lim,rwarp,distance); blur(distance,dsv[i],Size(2*r+1,2*r+1)); } Size size = dest.size(); Mat cost = Mat::ones(size,VOLUME_TYPE)*255; Mat mask; const int imsize = size.area(); for(int i=0;i<range;i++) { Mat pcost; cost.copyTo(pcost); min(pcost,dsv[i],cost); compare(pcost,cost,mask,cv::CMP_NE); dest.setTo(i+minDisparity,mask); } }
  • 15. ハミング距離サンプル 画像Aと画像Bの各画素のハミング距離計測のサンプル(OpenCVによる実装) void calcHammingDistance8u(Mat& src1, Mat& src2, Mat& dest) { if(dest.empty())dest.create(src1.size(),CV_8U); int i,j; uchar* s1 = src1.ptr<uchar>(0); uchar* s2 = src2.ptr<uchar>(0); uchar* d = dest.ptr<uchar>(0); for(j=src1.rows;j--;) { for(i=src1.cols;i--;) { *d = _mm_popcnt_u32((unsigned int)(*s1^*s2)); s1++;s2++,d++; } } }
  • 16. 画像のCENSUS変換サンプル 9x1の横長の窓でのCENSUS変換.条件を満たしたら1とのbit orを取って, 次に備えてbit shiftしているだけ void censusTrans8u_8x1(Mat& src, Mat& dest) { if(dest.empty())dest.create(src.size(),CV_8U); const int r=4; const int r2=2*r; Mat im;copyMakeBorder(src,im,0,0,r,r,cv::BORDER_REPLICATE); int i,j,n; uchar* s = im.ptr<uchar>(0);s+=r; uchar* d = dest.ptr<uchar>(0); for(j=0;j<src.rows;j++) { for(i=0;i<src.cols;i++) { uchar val = 0;//init value uchar* ss=s-r; for(n = 0;n<r;n++) { val = (*ss<*s) ? val|1 : val; ss++; val <<=1; } ss++;//skip r=0 for(n = 0;n<r;n++) { val = (*ss<*s) ? val|1 : val; ss++; val <<=1; } *d=val; d++; s++; } s+=r2; } }