मैं छवि प्रसंस्करण के लिए एक बहु गणना शेडर लागू करने के लिए कोशिश कर रहा हूँ। प्रत्येक पास में एक इनपुट छवि और एक आउटपुट छवि है। अगली पास 'इनपुट छवि पिछले वाले' आउटपुट है।ओपन गणना शेडर - अजीब परिणाम
यह मैं ओपन में गणना शेडर का उपयोग कर तो वहाँ मेरी सेटअप के साथ कुछ समस्या हो सकती है के लिए पहली बार है। मैं ओपनसीवी की मैट का उपयोग कंटेनर को पढ़ने/कॉपी करने के लिए कंटेनर के रूप में कर रहा हूं।
कोड के कुछ भागों जो समस्या से संबंधित नहीं है तो मैं शामिल नहीं किया था रहे हैं। इनमें से कुछ हिस्सों में छवि लोड करना या संदर्भ आरंभ करना शामिल है।
प्रारंभ:
//texture init
glGenTextures(1, &feedbackTexture_);
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D, feedbackTexture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
glGenTextures(1, &resultTexture_);
glActiveTexture(GL_TEXTURE0+1);
glBindTexture(GL_TEXTURE_2D, resultTexture_);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glBindTexture(GL_TEXTURE_2D, 0);
// shader init
computeShaderID = glCreateShader(GL_COMPUTE_SHADER);
glShaderSource(computeShaderID, 1, &computeShaderSourcePtr, &computeShaderLength);
glCompileShader(computeShaderID);
programID = glCreateProgram();
glAttachShader(programID, computeShaderID);
glLinkProgram(programID);
glDeleteShader(computeShaderID);
छायांकर्ता कोड:
//shader code (simple invert)
#version 430
layout (local_size_x = 1, local_size_y = 1) in;
layout (location = 0, binding = 0, /*format*/ rgba32f) uniform readonly image2D inImage;
layout (location = 1, binding = 1, /*format*/ rgba32f) uniform writeonly image2D resultImage;
uniform writeonly image2D image;
void main()
{
// Acquire the coordinates to the texel we are to process.
ivec2 texelCoords = ivec2(gl_GlobalInvocationID.xy);
// Read the pixel from the first texture.
vec4 pixel = imageLoad(inImage, texelCoords);
pixel.rgb = 1. - pixel.rgb;
imageStore(resultImage, texelCoords, pixel);
}
उपयोग:
cv::Mat image = loadImage().clone();
cv::Mat result(image.rows,image.cols,image.type());
// These get the appropriate enums used by glTexImage2D
GLenum internalformat = GLUtils::getMatOpenGLImageFormat(image);
GLenum format = GLUtils::getMatOpenGLFormat(image);
GLenum type = GLUtils::getMatOpenGLType(image);
int dispatchX = 1;
int dispatchY = 1;
for (int i = 0; i < shaderPasses_.size(); ++i)
{
// Update textures
glBindTexture(GL_TEXTURE_2D, feedbackTexture_);
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, result.cols, result.rows, 0, format, type, result.data);
glBindTexture(GL_TEXTURE_2D, resultTexture_);
glTexImage2D(GL_TEXTURE_2D, 0, internalformat, image.cols, image.rows, 0, format, type, 0);
glBindTexture(GL_TEXTURE_2D, 0);
glClear(GL_COLOR_BUFFER_BIT);
std::shared_ptr<Shader> shaderPtr = shaderPasses_[i];
// Enable shader
shaderPtr->enable();
{
// Bind textures
// location = 0, binding = 0
glUniform1i(0,0);
// binding = 0
glBindImageTexture(0, feedbackTexture_, 0, GL_FALSE, 0, GL_READ_ONLY, internalformat);
// location = 1, binding = 1
glUniform1i(1,1);
// binding = 1
glBindImageTexture(1, resultTexture_, 0, GL_FALSE, 0, GL_WRITE_ONLY, internalformat);
// Dispatch rendering
glDispatchCompute((GLuint)image.cols/dispatchX,(GLuint)image.rows/dispatchY,1);
// Barrier will synchronize
glMemoryBarrier(GL_TEXTURE_UPDATE_BARRIER_BIT);
}
// disable shader
shaderPtr->disable();
// Here result is now the result of the last pass.
}
कभी कभी मैं अजीब परिणाम (glitchy बनावट, आंशिक रूप से प्रदान की गई बनावट) मिलता है, यह भी पहले पिक्सेल (0,0 पर) कभी-कभी लिखा नहीं जाता है। क्या मैंने सब कुछ ठीक से स्थापित किया था या क्या मुझे कुछ याद आ रही है? ऐसा लगता है कि बनावट के साथ इस पद्धति वास्तव में धीमी है, वहाँ किसी भी विकल्प है जो प्रदर्शन में वृद्धि होगी है?
संपादित 1:मेमोरीबियर ध्वज बदल गया।
कड़ाई से बोलते हुए, आपका प्रारंभिक कॉल 'सीवी :: मट परिणाम (image.rows, image.cols, image.type());' _vocate_ छवि क्लिप बफर होना चाहिए, जैसा कि 'cv :: mat :: create' के समान है, हालांकि यह पिक्सेल मान _initialize_ नहीं है। 'सीवी :: मैट :: शून्य 'और' सीवी :: मैट :: वाले' दोनों पिक्सेल मान आवंटित और आरंभ करते हैं। – AldurDisciple
हाँ आप सही हैं, मैं अपना जवाब अपडेट करूंगा। –