void ShapeEstimation::cropMask(ImageReader mask, std::vector<float> &pixelLuminances){ int rows = mask.getImageHeight(); int cols = mask.getImageWidth(); for(int row = 0; row < rows; row++){ for(int col = 0; col < cols; col++){ QColor maskColor = QColor(mask.pixelAt(row, col)); int index = mask.indexAt(row, col); if(maskColor.red() > 150){ } else { if(DEPTHMAPBACKGROUND){ pixelLuminances[index] = 1.0f; } else { pixelLuminances[index] = 0.0f; } } } } }
void ShapeEstimation::estimateShape(ImageReader imageIn, ImageReader mask, std::vector<float>& depthMap, std::vector<Vector3f>& normalMap, std::vector<float> &gradientX, std::vector<float> &gradientY){ BilateralFilter bf; int rows = imageIn.getImageHeight(); int cols = imageIn.getImageWidth(); float sigma = 0.0f; std::vector<float> luminances = computePixelLuminance(imageIn, mask, sigma); m_luminances = luminances; sigmoidalCompression(luminances, sigma); std::cout << rows << " " << cols << std::endl; float bilateralSigmaSpatial = m_bilateralSmoothing * float(cols); float bilateralSigmaL = 255.0f; std::cout << "convolve" << std::endl; luminances = bf.convolve(imageIn, luminances, bilateralSigmaSpatial, bilateralSigmaL); std::cout << "inversion" << std::endl; sigmoidalInversion(luminances, sigma); //cropMask(mask, luminances); std::vector<Vector3f> normals = gradientField(mask, luminances, gradientX, gradientY); if(DEBUG){ QImage output(cols, rows, QImage::Format_RGB32); QRgb *depthMap = reinterpret_cast<QRgb *>(output.bits()); for(int i = 0; i < rows; i++){ for(int j = 0; j < cols; j++){ int index = imageIn.indexAt(i, j); float color = luminances[index] * 255.0f; QColor colorOut = QColor(floor(color), floor(color), floor(color)); depthMap[imageIn.indexAt(i, j)] = colorOut.rgb(); } } output.save("images/depthMap.png"); } // write out normal map if(DEBUG){ float maxRed = 0.0f; float maxGreen = 0.0f; float minRed = 10000.0f; float minGreen = 10000.0f; for(int i = 0; i < rows; i++){ for(int j = 0; j < cols; j++){ int index = imageIn.indexAt(i, j); float red = normals[index](0); if(red > maxRed){ maxRed = red; } if(red < minRed){ minRed = red; } float green = normals[index](1) ; if(green > maxGreen){ maxGreen = green; } if(green < minGreen){ minGreen = green; } } } QImage output(cols, rows, QImage::Format_RGB32); QRgb *normalMap = reinterpret_cast<QRgb *>(output.bits()); for(int i = 0; i < rows; i++){ for(int j = 0; j < cols; j++){ int index = mask.indexAt(i, j); QColor colorOut = QColor(0,0,0); if(QColor(mask.pixelAt(i,j)).red() > 150){ float red = (255) * (normals[index](0) - minRed)/(maxRed - minRed); float green = (255) * (normals[index](1) - minGreen)/(maxGreen - minGreen); float blue = normals[index](2) * 255.0f; colorOut = QColor(fabs(floor(red)), fabs(floor(green)), floor(blue)); } normalMap[mask.indexAt(i, j)] = colorOut.rgb(); } } output.save("images/normalmap.png"); } depthMap = luminances; normalMap = normals; }
std::vector<Vector3f> ShapeEstimation::gradientField(ImageReader mask, std::vector<float> &pixelLuminances, std::vector<float> &gradientX, std::vector<float> &gradientY){ int rows = mask.getImageHeight(); int cols = mask.getImageWidth(); float gxNormalize = 0.0f; float gyNormalize = 0.0f; for(int row = 0; row < rows; row++){ for(int col = 0; col < cols; col++){ int index = mask.indexAt(row, col); if(row + 1 < rows){ int indexUp = mask.indexAt(row + 1, col); float dY = pixelLuminances[indexUp] - pixelLuminances[index]; gradientY.push_back(dY); if(fabs(dY) > gyNormalize){ gyNormalize = fabs(dY); } } else { gradientY.push_back(0.0f); } if(col + 1 < cols){ int indexRight = mask.indexAt(row, col+1); float dX = pixelLuminances[indexRight] - pixelLuminances[index]; gradientX.push_back(dX); if(fabs(dX) > gxNormalize){ gxNormalize = fabs(dX); } } else { gradientX.push_back(0.0f); } } } assert(gradientX.size() == gradientY.size()); for(int i = 0; i < gradientX.size(); i++){ gradientX[i] = gradientReshapeRecursive(gradientX[i]/gxNormalize, m_curvature) * gxNormalize; } for(int i = 0; i < gradientY.size(); i++){ gradientY[i] = gradientReshapeRecursive(gradientY[i]/gyNormalize, m_curvature) * gyNormalize; } std::vector<Vector3f> normals; for(int i = 0; i < rows; i++){ for(int j = 0; j < cols; j++){ QColor maskColor = QColor(mask.pixelAt(i,j)); if(maskColor.red() > 150){ Eigen::Vector3f gx = Vector3f(1.0f, 0.0f, gradientX[mask.indexAt(i,j)]); Eigen::Vector3f gy = Vector3f(0.0f, 1.0f, gradientY[mask.indexAt(i,j)]); Eigen::Vector3f normal = (gx.cross(gy)); normal = normal.normalized(); normals.push_back(normal); } else { normals.push_back(Vector3f(0.0,0.0,0.0)); } } } //pixelLuminances = gradientX; return normals; }