我在OpenCV中使用UIGestureRecognizer
类型的大小为img
的c ++中的图像mxn
。
我有另一个大小为CV_8UC3
的{{1}}向量b
"水平"分为两部分:
1xn
img
,
其中1 <= b(1,col)&lt; = m(1 <= col&lt; = n)。
对于图像的这两部分,我希望协方差矩阵upper_part = {(row,col)|1<=col<=n, 1<=row<=b(1,col)}
和lower_part = {(row,col)|1<=col<=n, b(1,col)<row<=m}
类型为&#34; per&#34;渠道。这意味着得到的矩阵应该具有3x3的大小,并且应该像:
M_u
,
其中N_u是上部的元素数量,mu_u是描述上部平均RGB值的3x1向量,M_l
是3x1向量,其中RGB值为M_u = 1/(N_u-1) * sum_{(row,col)\in upper_part} (img(row,col)-mu_u)*(img(row,col)-mu_u)^T
img(row,col)
。考虑到img
,(row,col)
与M_l
和N_l
等效计算。
此外,我(有时)还必须计算mu_l
图像的协方差。当然,矩阵只是一个标量。
主要针对lower_part
类型是否有解决方案?如果是,是否有适用于CV_8UC1
类型图像的解决方案?
我目前的解决方案是迭代每个像素并通过分别获得CV_8UC3
或CV_8UC1
的值来计算它(首先是均值,然后是协方差,因此所有像素都有两个循环) ,但我所听到的,现在看到的是,这个功能非常低效/慢。正如我在循环中计算img.at<Vec3b>(row,col)
和img.at<unsigned char>(row,col)
的过程一样,我希望有效地推导出协方差。
有什么想法吗?
谢谢。
PS:M_u
和M_l
。
答案 0 :(得分:0)
可以在所有像素的单个循环迭代中计算协方差。
我有以下代码迭代图像的整个像素集,只需一次并计算协方差矩阵。这可以很好地扩展到您的分割图像的情况。
{
//img is a CV_8UC3 image in RGB format
Vec3f sumOfPixels=Vec3f(0,0,0);
float sumRR=0, sumRG=0, sumRB=0, sumGG=0, sumGB=0, sumBB=0;
Mat covarianceMat = Mat::zeros(3, 3, CV_32FC1);
for(int r= 0; r < img.rows; ++r) {
for(int c=0; c < img.cols; ++c) {
const Vec3b ¤tPixel = img.at<Vec3b>(Point(c,r));
sumOfPixels += Vec3b(currentPixel[0], currentPixel[1], currentPixel[2]);
sumRR += currentPixel[0] * currentPixel[0];
sumRG += currentPixel[0] * currentPixel[1];
sumRB += currentPixel[0] * currentPixel[2];
sumGG += currentPixel[1] * currentPixel[1];
sumGB += currentPixel[1] * currentPixel[2];
sumBB += currentPixel[2] * currentPixel[2];
}
}
int nPixels = img.rows * img.cols;
assert(nPixels > 0);
Vec3f avgOfPixels = sumOfPixels / nPixels;
covarianceMat.at<float>(0,0) = sumRR/nPixels - avgOfPixels[0]*avgOfPixels[0];
covarianceMat.at<float>(0,1) = sumRG/nPixels - avgOfPixels[0]*avgOfPixels[1];
covarianceMat.at<float>(0,2) = sumRB/nPixels - avgOfPixels[0]*avgOfPixels[2];
covarianceMat.at<float>(1,1) = sumGG/nPixels - avgOfPixels[1]*avgOfPixels[1];
covarianceMat.at<float>(1,2) = sumGB/nPixels - avgOfPixels[1]*avgOfPixels[2];
covarianceMat.at<float>(2,2) = sumBB/nPixels - avgOfPixels[2]*avgOfPixels[2];
covarianceMat.at<float>(1,0) = covarianceMat.at<float>(0,1);
covarianceMat.at<float>(2,0) = covarianceMat.at<float>(0,2);
covarianceMat.at<float>(2,1) = covarianceMat.at<float>(1,2);
cout << "covariance of image: " << covarianceMat << endl;
}
在计算完整图像的协方差(即:不是分割图像)的情况下,您可以使用opencv&#39; calcCovarMatrix&#39;来检查协方差是否正确。同样。
Mat img_copy = img;
assert(img.type() == img_copy.type());
img_copy = img.reshape(1, img.rows *img.cols);
cv::Mat covar, mean;
cv::calcCovarMatrix(img_copy, covar, mean, CV_COVAR_NORMAL | CV_COVAR_ROWS );
covar /= (img.rows * img.cols);
std::cout << "covariance through opencv: " << covar << std::endl;