双目相机的内参外参:
双目相机的四个坐标系:
双目相机矫正:
双目相机用公式推导法求深度图(需要视差)
双目相机求视差的算法:SAD匹配算法、BM算法、SGBM算法、GC算法等
https://www.cnblogs.com/zyly/p/9373991.html
https://www.cnblogs.com/riddick/p/8486223.html
https://www.cnblogs.com/paladinzxl/p/9366670.html
立体匹配相关代码:
https://www.cnblogs.com/polly333/p/5130375.html
sad算法:最简单的思路。。。。
https://www.cnblogs.com/Crazy-Dog123/articles/5043864.html
关于视差图的理解:
https://blog.csdn.net/cyem1/article/details/80736878
sad:
//
// main.cpp
// bioversion
//
// Created by w e il a n lin on 2019/12/10.
// Copyright © 2019 w e il a n lin. All rights reserved.
//
#include<iostream>
#include<opencv/cv.h>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/*Half of the window size for the census transform*/
int hWin = 11;
int compareLength = (2*hWin+1)*(2*hWin+1);
cout<<"hWin: "<<hWin<<"; "<<"compare length: "<<compareLength<<endl;
cout<<"SAD test"<<endl;
// char stopKey;
IplImage * leftImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/l.png",0);
IplImage * rightImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/r.png",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
IplImage * SADImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * MatchLevelImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
int minDBounds = 0;
int maxDBounds = 31;
cvNamedWindow("Left",1);
cvNamedWindow("Right",1);
cvNamedWindow("Census",1);
cvNamedWindow("MatchLevel",1);
cvShowImage("Left",leftImage);
cvShowImage("Right",rightImage);
/*Census Transform */
int i,j ,m,n,k;
unsigned char centerPixel = 0;
unsigned char neighborPixel = 0;
int bitCount = 0;
unsigned int bigger = 0;
int sum = 0;
unsigned int *matchLevel = new unsigned int[maxDBounds - minDBounds + 1];
int tempMin = 0;
int tempIndex = 0;
unsigned char* dst;
unsigned char* leftSrc = NULL;
unsigned char* rightSrc = NULL;
unsigned char leftPixel = 0;
unsigned char rightPixel =0;
unsigned char subPixel = 0;
for(i = 0 ; i < leftImage->height;i++){
for(j = 0; j< leftImage->width;j++){
for (k = minDBounds;k <= maxDBounds;k++)
{
sum = 0;
for (m = i-hWin; m <= i + hWin;m++)
{
for (n = j - hWin; n <= j + hWin;n++)
{
if (m < 0 || m >= imageHeight || n <0 || n >= imageWidth )
{
subPixel = 0;
}else if (n + k >= imageWidth)
{
subPixel = 0;
}else
{
leftSrc = (unsigned char*)leftImage->imageData
+ m*leftImage->widthStep + n + k;
rightSrc = (unsigned char*)rightImage->imageData
+ m*rightImage->widthStep + n;
leftPixel = *leftSrc;
rightPixel = *rightSrc;
if (leftPixel > rightPixel)
{
subPixel = leftPixel - rightPixel;
}else
{
subPixel = rightPixel -leftPixel;
}
}
sum += subPixel;
}
}
matchLevel[k] = sum;
//cout<<sum<<endl;
}
/*寻找最佳匹配点*/
// matchLevel[0] = 1000000;
tempMin = 0;
tempIndex = 0;
for ( m = 1;m < maxDBounds - minDBounds + 1;m++)
{
//cout<<matchLevel[m]<<endl;
if (matchLevel[m] < matchLevel[tempIndex])
{
tempMin = matchLevel[m];
tempIndex = m;
}
}
dst = (unsigned char *)SADImage->imageData + i*SADImage->widthStep + j;
//cout<<"index: "<<tempIndex<<" ";
*dst = tempIndex*8;
dst = (unsigned char *)MatchLevelImage->imageData + i*MatchLevelImage->widthStep + j;
*dst = tempMin;
//cout<<"min: "<<tempMin<<" ";
//cout<< tempIndex<<" " <<tempMin<<endl;
}
//cvWaitKey(0);
}
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&leftImage);
cvReleaseImage(&rightImage);
return 0;
}
ssd:
在这里插入代码片
#include
#include<opencv/cv.h>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/Half of the window size for the census transform/
int hWin = 11;
int compareLength = (2hWin+1)(2*hWin+1);
cout<<"hWin: "<<hWin<<"; "<<"compare length: "<<compareLength<<endl;
cout<<"SAD test"<<endl;
// char stopKey;
IplImage * leftImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/l.png",0);
IplImage * rightImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/r.png",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
IplImage * SADImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * MatchLevelImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
int minDBounds = 0;
int maxDBounds = 31;
cvNamedWindow("Left",1);
cvNamedWindow("Right",1);
cvNamedWindow("Census",1);
cvNamedWindow("MatchLevel",1);
cvShowImage("Left",leftImage);
cvShowImage("Right",rightImage);
/*Census Transform */
int i,j ,m,n,k;
unsigned char centerPixel = 0;
unsigned char neighborPixel = 0;
int bitCount = 0;
unsigned int bigger = 0;
int sum = 0;
unsigned int *matchLevel = new unsigned int[maxDBounds - minDBounds + 1];
int tempMin = 0;
int tempIndex = 0;
unsigned char* dst;
unsigned char* leftSrc = NULL;
unsigned char* rightSrc = NULL;
unsigned char leftPixel = 0;
unsigned char rightPixel =0;
unsigned char subPixel = 0;
for(i = 0 ; i < leftImage->height;i++){
for(j = 0; j< leftImage->width;j++){
for (k = minDBounds;k <= maxDBounds;k++)
{
sum = 0;
for (m = i-hWin; m <= i + hWin;m++)
{
for (n = j - hWin; n <= j + hWin;n++)
{
if (m < 0 || m >= imageHeight || n <0 || n >= imageWidth )
{
subPixel = 0;
}else if (n + k >= imageWidth)
{
subPixel = 0;
}else
{
leftSrc = (unsigned char*)leftImage->imageData
+ m*leftImage->widthStep + n + k;
rightSrc = (unsigned char*)rightImage->imageData
+ m*rightImage->widthStep + n;
leftPixel = *leftSrc;
rightPixel = *rightSrc;
if (leftPixel > rightPixel)
{
subPixel = leftPixel - rightPixel;
}else
{
subPixel = rightPixel -leftPixel;
}
}
sum += subPixel*subPixel;
}
}
matchLevel[k] = sum;
//cout<<sum<<endl;
}
/*寻找最佳匹配点*/
// matchLevel[0] = 1000000;
tempMin = 0;
tempIndex = 0;
for ( m = 1;m < maxDBounds - minDBounds + 1;m++)
{
//cout<<matchLevel[m]<<endl;
if (matchLevel[m] < matchLevel[tempIndex])
{
tempMin = matchLevel[m];
tempIndex = m;
}
}
dst = (unsigned char *)SADImage->imageData + i*SADImage->widthStep + j;
//cout<<"index: "<<tempIndex<<" ";
*dst = tempIndex*8;
dst = (unsigned char *)MatchLevelImage->imageData + i*MatchLevelImage->widthStep + j;
*dst = tempMin;
//cout<<"min: "<<tempMin<<" ";
//cout<< tempIndex<<" " <<tempMin<<endl;
}
//cvWaitKey(0);
}
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&leftImage);
cvReleaseImage(&rightImage);
return 0;
}
zssd:
#include<iostream>
#include<opencv/cv.h>
#include<opencv2/highgui/highgui.hpp>
using namespace std;
int GetHammingWeight(unsigned int value);
int main(){
/*Half of the window size for the census transform*/
int hWin = 11;
int compareLength = (2*hWin+1)*(2*hWin+1);
cout<<"hWin: "<<hWin<<"; "<<"compare length: "<<compareLength<<endl;
cout<<"ZSSD test"<<endl;
// char stopKey;
/* IplImage * leftImage = cvLoadImage("l2.jpg",0);
IplImage * rightImage = cvLoadImage("r2.jpg",0);*/
IplImage * leftImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/l.png",0);
IplImage * rightImage = cvLoadImage("/Users/weilanlin/Desktop/bioversion/bioversion/r.png",0);
int imageWidth = leftImage->width;
int imageHeight =leftImage->height;
IplImage * SADImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
IplImage * MatchLevelImage = cvCreateImage(cvGetSize(leftImage),leftImage->depth,1);
int minDBounds = 0;
int maxDBounds = 31;
cvNamedWindow("Left",1);
cvNamedWindow("Right",1);
cvNamedWindow("Census",1);
cvNamedWindow("MatchLevel",1);
cvShowImage("Left",leftImage);
cvShowImage("Right",rightImage);
/*Census Transform */
int i,j ,m,n,k;
unsigned char centerPixel = 0;
unsigned char neighborPixel = 0;
int bitCount = 0;
unsigned int bigger = 0;
int sumLeft = 0;
int sumRight = 0;
int sum =0;
int zSumLeft = 0;
int zSumRight = 0;
unsigned int *matchLevel = new unsigned int[maxDBounds - minDBounds + 1];
int tempMin = 0;
int tempIndex = 0;
unsigned char* dst;
unsigned char* leftSrc = NULL;
unsigned char* rightSrc = NULL;
unsigned char leftPixel = 0;
unsigned char rightPixel =0;
unsigned char subPixel = 0;
unsigned char meanLeftPixel = 0;
unsigned char meanRightPixel = 0;
for(i = 0 ; i < leftImage->height;i++){
for(j = 0; j< leftImage->width;j++){
/*均值计算 */
for (k = minDBounds;k <= maxDBounds;k++)
{
sumLeft = 0;
sumRight = 0;
for (m = i-hWin; m <= i + hWin;m++)
{
for (n = j - hWin; n <= j + hWin;n++)
{
if (m < 0 || m >= imageHeight || n <0 || n >= imageWidth )
{
sumLeft += 0;
}else {
leftSrc = (unsigned char*)leftImage->imageData
+ m*leftImage->widthStep + n + k;
leftPixel = *leftSrc;
sumLeft += leftPixel;
}
if (m < 0 || m >= imageHeight || n + k <0 || n +k >= imageWidth)
{
sumRight += 0;
}else
{
rightSrc = (unsigned char*)rightImage->imageData
+ m*rightImage->widthStep + n;
rightPixel = *rightSrc;
sumRight += rightPixel;
}
}
}
meanLeftPixel = sumLeft/compareLength;
meanRightPixel = sumRight/compareLength;
/*ZSSD*/
sum = 0;
for (m = i-hWin; m <= i + hWin;m++)
{
for (n = j - hWin; n <= j + hWin;n++)
{
if (m < 0 || m >= imageHeight || n <0 || n >= imageWidth )
{
//zSumLeft += 0;
leftPixel = 0;
}else {
leftSrc = (unsigned char*)leftImage->imageData
+ m*leftImage->widthStep + n + k;
leftPixel = *leftSrc;
//zSumLeft += (leftPixel - meanLeftPixel)*(leftPixel -meanLeftPixel);
}
if (m < 0 || m >= imageHeight || n + k <0 || n +k >= imageWidth)
{
//zSumRight += 0;
rightPixel = 0;
}else
{
rightSrc = (unsigned char*)rightImage->imageData
+ m*rightImage->widthStep + n;
rightPixel = *rightSrc;
// zSumRight += (rightPixel - meanRightPixel)*(rightPixel - meanRightPixel);
}
sum += ((rightPixel - meanRightPixel)-(leftPixel -meanLeftPixel))
*((rightPixel - meanRightPixel)-(leftPixel -meanLeftPixel));
}
}
matchLevel[k] = sum;
//cout<<sum<<endl;
}
/*寻找最佳匹配点*/
// matchLevel[0] = 1000000;
tempMin = 0;
tempIndex = 0;
for ( m = 1;m < maxDBounds - minDBounds + 1;m++)
{
//cout<<matchLevel[m]<<endl;
if (matchLevel[m] < matchLevel[tempIndex])
{
tempMin = matchLevel[m];
tempIndex = m;
}
}
dst = (unsigned char *)SADImage->imageData + i*SADImage->widthStep + j;
//cout<<"index: "<<tempIndex<<" ";
*dst = tempIndex*8;
dst = (unsigned char *)MatchLevelImage->imageData + i*MatchLevelImage->widthStep + j;
*dst = tempMin;
//cout<<"min: "<<tempMin<<" ";
//cout<< tempIndex<<" " <<tempMin<<endl;
}
// cvWaitKey(0);
}
cvShowImage("Census",SADImage);
cvShowImage("MatchLevel",MatchLevelImage);
cvSaveImage("depth.jpg",SADImage);
cvSaveImage("matchLevel.jpg",MatchLevelImage);
cout<<endl<<"Over"<<endl;
cvWaitKey(0);
cvDestroyAllWindows();
cvReleaseImage(&leftImage);
cvReleaseImage(&rightImage);
return 0;
}
census: