cv::imshow in opencv is only displaying parts of a composite image, but displaying the parts separately...
Objective and problem
I'm trying to process a video file on the fly using OpenCV 3.4.1 by grabbing each frame, converting to grayscale, then doing Canny edge detection on it. In order to display the images (on the fly as well), I created a Mat class with 3 additional headers that is three times as wide as the original frame. The 3 extra headers represent the images I would like to display in the composite, and are positioned to the 1st, 2nd and 3rd horizontal segment of the composite.
After image processing however, the display of the composite image is not as expected: the first segment (where the original frame should be) is completely black, while the other segments (of processed images) are displayed fine. If, on the other hand, I display the ROIs one by one in separate windows, all the images look fine.
These are the things I tried to overcome this issue:
- use .copyTo to actually copy the data into the appropriate image segments. The result was the same.
- I put the Canny image to the compOrigPart ROI, and it did display in the first segment, so it is not a problem with the definition of the ROIs.
- Define the composite as three channel image
- In the loop convert it to grayscale
- put processed images into it
- convert back to BGR
- put the original in.
This time around the whole composite was black, nothing showed.
- As per gameon67's suggestion, I tried to create a namedWindow as well, but that doesn't help either.
Code:
int main() {
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
int frameWidth = vid.get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = vid.get(cv::CAP_PROP_FRAME_HEIGHT);
int frameFormat = vid.get(cv::CAP_PROP_FORMAT);
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame;
cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat);
cv::Mat compOrigPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(0, frameWidth));
cv::Mat compBwPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth, frameWidth*2));
cv::Mat compEdgePart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth*2, frameWidth*3));
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
compOrigPart = frame;
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Questions
- Why can't I display the entirety of the composite image in a single window, while displaying them separately is OK?
- What is the difference between these displays? The data is obviously there, as evidenced by the separate windows.
- Why only the original frame is misbehaving?
c++ image opencv highgui
add a comment |
Objective and problem
I'm trying to process a video file on the fly using OpenCV 3.4.1 by grabbing each frame, converting to grayscale, then doing Canny edge detection on it. In order to display the images (on the fly as well), I created a Mat class with 3 additional headers that is three times as wide as the original frame. The 3 extra headers represent the images I would like to display in the composite, and are positioned to the 1st, 2nd and 3rd horizontal segment of the composite.
After image processing however, the display of the composite image is not as expected: the first segment (where the original frame should be) is completely black, while the other segments (of processed images) are displayed fine. If, on the other hand, I display the ROIs one by one in separate windows, all the images look fine.
These are the things I tried to overcome this issue:
- use .copyTo to actually copy the data into the appropriate image segments. The result was the same.
- I put the Canny image to the compOrigPart ROI, and it did display in the first segment, so it is not a problem with the definition of the ROIs.
- Define the composite as three channel image
- In the loop convert it to grayscale
- put processed images into it
- convert back to BGR
- put the original in.
This time around the whole composite was black, nothing showed.
- As per gameon67's suggestion, I tried to create a namedWindow as well, but that doesn't help either.
Code:
int main() {
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
int frameWidth = vid.get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = vid.get(cv::CAP_PROP_FRAME_HEIGHT);
int frameFormat = vid.get(cv::CAP_PROP_FORMAT);
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame;
cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat);
cv::Mat compOrigPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(0, frameWidth));
cv::Mat compBwPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth, frameWidth*2));
cv::Mat compEdgePart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth*2, frameWidth*3));
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
compOrigPart = frame;
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Questions
- Why can't I display the entirety of the composite image in a single window, while displaying them separately is OK?
- What is the difference between these displays? The data is obviously there, as evidenced by the separate windows.
- Why only the original frame is misbehaving?
c++ image opencv highgui
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
compOrigPart = frame
is a simple assignment of theMat
(which is kind of like a shared pointer). What you want is to copy the contents offrame
to the ROI represented bycompOrigPart
...
– Dan Mašek
Jan 18 at 2:54
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents offrame
to the ROI doesn't help.
– pusrob
Jan 18 at 18:26
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data typecompositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).
– Dan Mašek
Jan 19 at 13:08
add a comment |
Objective and problem
I'm trying to process a video file on the fly using OpenCV 3.4.1 by grabbing each frame, converting to grayscale, then doing Canny edge detection on it. In order to display the images (on the fly as well), I created a Mat class with 3 additional headers that is three times as wide as the original frame. The 3 extra headers represent the images I would like to display in the composite, and are positioned to the 1st, 2nd and 3rd horizontal segment of the composite.
After image processing however, the display of the composite image is not as expected: the first segment (where the original frame should be) is completely black, while the other segments (of processed images) are displayed fine. If, on the other hand, I display the ROIs one by one in separate windows, all the images look fine.
These are the things I tried to overcome this issue:
- use .copyTo to actually copy the data into the appropriate image segments. The result was the same.
- I put the Canny image to the compOrigPart ROI, and it did display in the first segment, so it is not a problem with the definition of the ROIs.
- Define the composite as three channel image
- In the loop convert it to grayscale
- put processed images into it
- convert back to BGR
- put the original in.
This time around the whole composite was black, nothing showed.
- As per gameon67's suggestion, I tried to create a namedWindow as well, but that doesn't help either.
Code:
int main() {
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
int frameWidth = vid.get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = vid.get(cv::CAP_PROP_FRAME_HEIGHT);
int frameFormat = vid.get(cv::CAP_PROP_FORMAT);
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame;
cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat);
cv::Mat compOrigPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(0, frameWidth));
cv::Mat compBwPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth, frameWidth*2));
cv::Mat compEdgePart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth*2, frameWidth*3));
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
compOrigPart = frame;
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Questions
- Why can't I display the entirety of the composite image in a single window, while displaying them separately is OK?
- What is the difference between these displays? The data is obviously there, as evidenced by the separate windows.
- Why only the original frame is misbehaving?
c++ image opencv highgui
Objective and problem
I'm trying to process a video file on the fly using OpenCV 3.4.1 by grabbing each frame, converting to grayscale, then doing Canny edge detection on it. In order to display the images (on the fly as well), I created a Mat class with 3 additional headers that is three times as wide as the original frame. The 3 extra headers represent the images I would like to display in the composite, and are positioned to the 1st, 2nd and 3rd horizontal segment of the composite.
After image processing however, the display of the composite image is not as expected: the first segment (where the original frame should be) is completely black, while the other segments (of processed images) are displayed fine. If, on the other hand, I display the ROIs one by one in separate windows, all the images look fine.
These are the things I tried to overcome this issue:
- use .copyTo to actually copy the data into the appropriate image segments. The result was the same.
- I put the Canny image to the compOrigPart ROI, and it did display in the first segment, so it is not a problem with the definition of the ROIs.
- Define the composite as three channel image
- In the loop convert it to grayscale
- put processed images into it
- convert back to BGR
- put the original in.
This time around the whole composite was black, nothing showed.
- As per gameon67's suggestion, I tried to create a namedWindow as well, but that doesn't help either.
Code:
int main() {
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
int frameWidth = vid.get(cv::CAP_PROP_FRAME_WIDTH);
int frameHeight = vid.get(cv::CAP_PROP_FRAME_HEIGHT);
int frameFormat = vid.get(cv::CAP_PROP_FORMAT);
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame;
cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat);
cv::Mat compOrigPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(0, frameWidth));
cv::Mat compBwPart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth, frameWidth*2));
cv::Mat compEdgePart(compositeFrame, cv::Range(0, frameHeight), cv::Range(frameWidth*2, frameWidth*3));
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
compOrigPart = frame;
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Questions
- Why can't I display the entirety of the composite image in a single window, while displaying them separately is OK?
- What is the difference between these displays? The data is obviously there, as evidenced by the separate windows.
- Why only the original frame is misbehaving?
c++ image opencv highgui
c++ image opencv highgui
edited Jan 18 at 18:45
pusrob
asked Jan 17 at 23:54
pusrobpusrob
112
112
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
compOrigPart = frame
is a simple assignment of theMat
(which is kind of like a shared pointer). What you want is to copy the contents offrame
to the ROI represented bycompOrigPart
...
– Dan Mašek
Jan 18 at 2:54
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents offrame
to the ROI doesn't help.
– pusrob
Jan 18 at 18:26
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data typecompositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).
– Dan Mašek
Jan 19 at 13:08
add a comment |
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
compOrigPart = frame
is a simple assignment of theMat
(which is kind of like a shared pointer). What you want is to copy the contents offrame
to the ROI represented bycompOrigPart
...
– Dan Mašek
Jan 18 at 2:54
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents offrame
to the ROI doesn't help.
– pusrob
Jan 18 at 18:26
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data typecompositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).
– Dan Mašek
Jan 19 at 13:08
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
compOrigPart = frame
is a simple assignment of the Mat
(which is kind of like a shared pointer). What you want is to copy the contents of frame
to the ROI represented by compOrigPart
...– Dan Mašek
Jan 18 at 2:54
compOrigPart = frame
is a simple assignment of the Mat
(which is kind of like a shared pointer). What you want is to copy the contents of frame
to the ROI represented by compOrigPart
...– Dan Mašek
Jan 18 at 2:54
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents of
frame
to the ROI doesn't help.– pusrob
Jan 18 at 18:26
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents of
frame
to the ROI doesn't help.– pusrob
Jan 18 at 18:26
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data type
compositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).– Dan Mašek
Jan 19 at 13:08
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data type
compositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).– Dan Mašek
Jan 19 at 13:08
add a comment |
2 Answers
2
active
oldest
votes
Your compBwPart and compEdgePart are grayscale images so the Mat type is CV8UC1 - single channel and therefore your compositeFrame is in grayscale too. If you want to combine these two images with a color image you have to convert it to BGR first and then fill the compOrigPart.
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
cv::cvtColor(compositeFrame, compositeFrame, cv::COLOR_GRAY2BGR);
frame.copyTo(compositeFrame(cv::Rect(0, 0, frameWidth, frameHeight)));
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor); //the rest of your code
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
andcv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.
– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned byvid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaningCV_8UC1
) for a color video, and then give me 3 channel frames.
– Dan Mašek
Jan 19 at 13:28
add a comment |
This is a combination of several issues.
The first problem is that you set the type of compositeFrame
to the value returned by vid.get(cv::CAP_PROP_FORMAT)
. Unfortunately that property doesn't seem entirely reliable -- I've just had it return 0 (meaning CV_8UC1
) after opening a color video, and then getting 3 channel (CV_8UC3
) frames. Since you want to have the compositeFrame
the same type as the input frame, this won't work.
To work around it, instead of using those properties, I'd lazy initialize compositeFrame
and the 3 ROIs after receiving the first frame (based on it's dimensions and type).
The next set of problems lies in those two statements:
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
In this case assumption is made that frame
is BGR (since you're trying to convert), meaning compositeFrame
and its ROIs are also BGR. Unfortunately, in both cases you're writing a grayscale image into the ROI. This will cause a reallocation, and the target Mat
will cease to be a ROI.
To correct this, use temporary Mat
s for the grayscale data, and use cvtColor
to turn it back to BGR to write into the ROIs.
Similar problem lies in the following statement:
compOrigPart = frame;
That's a shallow copy, meaning it will just make compOrigPart
another reference to frame
(and therefore it will cease to be a ROI of compositeFrame
).
What you need is a deep copy, using copyTo
(note that the data types still need to match, but that was fixed earlier).
Finally, even though you try to be flexible regarding the type of the input video (judging by the vid.get(cv::CAP_PROP_FORMAT)
), the rest of the code really assumes that the input is 3 channel, and will break if it isn't.
At the least, there should be some assertion to cover this expectation.
Putting this all together:
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame, frame_gray, edges_gray;
cv::Mat compositeFrame;
cv::Mat compOrigPart, compBwPart, compEdgePart; // ROIs
while (vid.read(frame)) {
if (frame.empty()) break;
if (compositeFrame.empty()) {
// The rest of code assumes video to be BGR (i.e. 3 channel)
CV_Assert(frame.type() == CV_8UC3);
// Lazy initialize once we have the first frame
compositeFrame = cv::Mat(frame.rows, frame.cols * 3, frame.type());
compOrigPart = compositeFrame(cv::Range::all(), cv::Range(0, frame.cols));
compBwPart = compositeFrame(cv::Range::all(), cv::Range(frame.cols, frame.cols * 2));
compEdgePart = compositeFrame(cv::Range::all(), cv::Range(frame.cols * 2, frame.cols * 3));
}
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::Canny(frame_gray, edges_gray, 100, 150);
// Deep copy data to the ROI
frame.copyTo(compOrigPart);
// The ROI is BGR, so we need to convert back
cv::cvtColor(frame_gray, compBwPart, cv::COLOR_GRAY2BGR);
cv::cvtColor(edges_gray, compEdgePart, cv::COLOR_GRAY2BGR);
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Screenshot of the composite window (using some random test video off the web):
Thanks. This seems to work, although I'm not sure why one can't rely onvid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.
– pusrob
Jan 21 at 17:10
add a comment |
Your Answer
StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");
StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);
StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});
function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54245965%2fcvimshow-in-opencv-is-only-displaying-parts-of-a-composite-image-but-displayi%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
Your compBwPart and compEdgePart are grayscale images so the Mat type is CV8UC1 - single channel and therefore your compositeFrame is in grayscale too. If you want to combine these two images with a color image you have to convert it to BGR first and then fill the compOrigPart.
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
cv::cvtColor(compositeFrame, compositeFrame, cv::COLOR_GRAY2BGR);
frame.copyTo(compositeFrame(cv::Rect(0, 0, frameWidth, frameHeight)));
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor); //the rest of your code
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
andcv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.
– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned byvid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaningCV_8UC1
) for a color video, and then give me 3 channel frames.
– Dan Mašek
Jan 19 at 13:28
add a comment |
Your compBwPart and compEdgePart are grayscale images so the Mat type is CV8UC1 - single channel and therefore your compositeFrame is in grayscale too. If you want to combine these two images with a color image you have to convert it to BGR first and then fill the compOrigPart.
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
cv::cvtColor(compositeFrame, compositeFrame, cv::COLOR_GRAY2BGR);
frame.copyTo(compositeFrame(cv::Rect(0, 0, frameWidth, frameHeight)));
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor); //the rest of your code
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
andcv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.
– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned byvid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaningCV_8UC1
) for a color video, and then give me 3 channel frames.
– Dan Mašek
Jan 19 at 13:28
add a comment |
Your compBwPart and compEdgePart are grayscale images so the Mat type is CV8UC1 - single channel and therefore your compositeFrame is in grayscale too. If you want to combine these two images with a color image you have to convert it to BGR first and then fill the compOrigPart.
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
cv::cvtColor(compositeFrame, compositeFrame, cv::COLOR_GRAY2BGR);
frame.copyTo(compositeFrame(cv::Rect(0, 0, frameWidth, frameHeight)));
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor); //the rest of your code
Your compBwPart and compEdgePart are grayscale images so the Mat type is CV8UC1 - single channel and therefore your compositeFrame is in grayscale too. If you want to combine these two images with a color image you have to convert it to BGR first and then fill the compOrigPart.
while (vid.read(frame)) {
if (frame.empty()) break;
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
cv::cvtColor(compositeFrame, compositeFrame, cv::COLOR_GRAY2BGR);
frame.copyTo(compositeFrame(cv::Rect(0, 0, frameWidth, frameHeight)));
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor); //the rest of your code
answered Jan 18 at 9:59
SushiSushi
515
515
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
andcv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.
– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned byvid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaningCV_8UC1
) for a color video, and then give me 3 channel frames.
– Dan Mašek
Jan 19 at 13:28
add a comment |
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
andcv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.
– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned byvid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaningCV_8UC1
) for a color video, and then give me 3 channel frames.
– Dan Mašek
Jan 19 at 13:28
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:
int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
and cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.– pusrob
Jan 18 at 18:39
Thanks, but I tried it as well (see: point 3 in "These are the things I tried to overcome this issue"). Your solution won't even run properly (throws exception), as the composite image has three channels (see:
int frameFormat = vid.get(cv::CAP_PROP_FORMAT))
and cv::Mat compositeFrame(frameHeight, frameWidth*3, frameFormat
). By trying to convert it from grayscale (which it is not), and exception is thrown. I described in point 3 a safer way to do what you suggest, but that didn't help either.– pusrob
Jan 18 at 18:39
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned by
vid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaning CV_8UC1
) for a color video, and then give me 3 channel frames.– Dan Mašek
Jan 19 at 13:28
@pusrob "as the composite image has three channels" -- no, that's just your assumption. All that code tells us that it has the type set to the value returned by
vid.get(cv::CAP_PROP_FORMAT))
. The problem is... that property is not always reliable. For example, I've just had it return 0 (meaning CV_8UC1
) for a color video, and then give me 3 channel frames.– Dan Mašek
Jan 19 at 13:28
add a comment |
This is a combination of several issues.
The first problem is that you set the type of compositeFrame
to the value returned by vid.get(cv::CAP_PROP_FORMAT)
. Unfortunately that property doesn't seem entirely reliable -- I've just had it return 0 (meaning CV_8UC1
) after opening a color video, and then getting 3 channel (CV_8UC3
) frames. Since you want to have the compositeFrame
the same type as the input frame, this won't work.
To work around it, instead of using those properties, I'd lazy initialize compositeFrame
and the 3 ROIs after receiving the first frame (based on it's dimensions and type).
The next set of problems lies in those two statements:
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
In this case assumption is made that frame
is BGR (since you're trying to convert), meaning compositeFrame
and its ROIs are also BGR. Unfortunately, in both cases you're writing a grayscale image into the ROI. This will cause a reallocation, and the target Mat
will cease to be a ROI.
To correct this, use temporary Mat
s for the grayscale data, and use cvtColor
to turn it back to BGR to write into the ROIs.
Similar problem lies in the following statement:
compOrigPart = frame;
That's a shallow copy, meaning it will just make compOrigPart
another reference to frame
(and therefore it will cease to be a ROI of compositeFrame
).
What you need is a deep copy, using copyTo
(note that the data types still need to match, but that was fixed earlier).
Finally, even though you try to be flexible regarding the type of the input video (judging by the vid.get(cv::CAP_PROP_FORMAT)
), the rest of the code really assumes that the input is 3 channel, and will break if it isn't.
At the least, there should be some assertion to cover this expectation.
Putting this all together:
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame, frame_gray, edges_gray;
cv::Mat compositeFrame;
cv::Mat compOrigPart, compBwPart, compEdgePart; // ROIs
while (vid.read(frame)) {
if (frame.empty()) break;
if (compositeFrame.empty()) {
// The rest of code assumes video to be BGR (i.e. 3 channel)
CV_Assert(frame.type() == CV_8UC3);
// Lazy initialize once we have the first frame
compositeFrame = cv::Mat(frame.rows, frame.cols * 3, frame.type());
compOrigPart = compositeFrame(cv::Range::all(), cv::Range(0, frame.cols));
compBwPart = compositeFrame(cv::Range::all(), cv::Range(frame.cols, frame.cols * 2));
compEdgePart = compositeFrame(cv::Range::all(), cv::Range(frame.cols * 2, frame.cols * 3));
}
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::Canny(frame_gray, edges_gray, 100, 150);
// Deep copy data to the ROI
frame.copyTo(compOrigPart);
// The ROI is BGR, so we need to convert back
cv::cvtColor(frame_gray, compBwPart, cv::COLOR_GRAY2BGR);
cv::cvtColor(edges_gray, compEdgePart, cv::COLOR_GRAY2BGR);
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Screenshot of the composite window (using some random test video off the web):
Thanks. This seems to work, although I'm not sure why one can't rely onvid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.
– pusrob
Jan 21 at 17:10
add a comment |
This is a combination of several issues.
The first problem is that you set the type of compositeFrame
to the value returned by vid.get(cv::CAP_PROP_FORMAT)
. Unfortunately that property doesn't seem entirely reliable -- I've just had it return 0 (meaning CV_8UC1
) after opening a color video, and then getting 3 channel (CV_8UC3
) frames. Since you want to have the compositeFrame
the same type as the input frame, this won't work.
To work around it, instead of using those properties, I'd lazy initialize compositeFrame
and the 3 ROIs after receiving the first frame (based on it's dimensions and type).
The next set of problems lies in those two statements:
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
In this case assumption is made that frame
is BGR (since you're trying to convert), meaning compositeFrame
and its ROIs are also BGR. Unfortunately, in both cases you're writing a grayscale image into the ROI. This will cause a reallocation, and the target Mat
will cease to be a ROI.
To correct this, use temporary Mat
s for the grayscale data, and use cvtColor
to turn it back to BGR to write into the ROIs.
Similar problem lies in the following statement:
compOrigPart = frame;
That's a shallow copy, meaning it will just make compOrigPart
another reference to frame
(and therefore it will cease to be a ROI of compositeFrame
).
What you need is a deep copy, using copyTo
(note that the data types still need to match, but that was fixed earlier).
Finally, even though you try to be flexible regarding the type of the input video (judging by the vid.get(cv::CAP_PROP_FORMAT)
), the rest of the code really assumes that the input is 3 channel, and will break if it isn't.
At the least, there should be some assertion to cover this expectation.
Putting this all together:
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame, frame_gray, edges_gray;
cv::Mat compositeFrame;
cv::Mat compOrigPart, compBwPart, compEdgePart; // ROIs
while (vid.read(frame)) {
if (frame.empty()) break;
if (compositeFrame.empty()) {
// The rest of code assumes video to be BGR (i.e. 3 channel)
CV_Assert(frame.type() == CV_8UC3);
// Lazy initialize once we have the first frame
compositeFrame = cv::Mat(frame.rows, frame.cols * 3, frame.type());
compOrigPart = compositeFrame(cv::Range::all(), cv::Range(0, frame.cols));
compBwPart = compositeFrame(cv::Range::all(), cv::Range(frame.cols, frame.cols * 2));
compEdgePart = compositeFrame(cv::Range::all(), cv::Range(frame.cols * 2, frame.cols * 3));
}
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::Canny(frame_gray, edges_gray, 100, 150);
// Deep copy data to the ROI
frame.copyTo(compOrigPart);
// The ROI is BGR, so we need to convert back
cv::cvtColor(frame_gray, compBwPart, cv::COLOR_GRAY2BGR);
cv::cvtColor(edges_gray, compEdgePart, cv::COLOR_GRAY2BGR);
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Screenshot of the composite window (using some random test video off the web):
Thanks. This seems to work, although I'm not sure why one can't rely onvid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.
– pusrob
Jan 21 at 17:10
add a comment |
This is a combination of several issues.
The first problem is that you set the type of compositeFrame
to the value returned by vid.get(cv::CAP_PROP_FORMAT)
. Unfortunately that property doesn't seem entirely reliable -- I've just had it return 0 (meaning CV_8UC1
) after opening a color video, and then getting 3 channel (CV_8UC3
) frames. Since you want to have the compositeFrame
the same type as the input frame, this won't work.
To work around it, instead of using those properties, I'd lazy initialize compositeFrame
and the 3 ROIs after receiving the first frame (based on it's dimensions and type).
The next set of problems lies in those two statements:
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
In this case assumption is made that frame
is BGR (since you're trying to convert), meaning compositeFrame
and its ROIs are also BGR. Unfortunately, in both cases you're writing a grayscale image into the ROI. This will cause a reallocation, and the target Mat
will cease to be a ROI.
To correct this, use temporary Mat
s for the grayscale data, and use cvtColor
to turn it back to BGR to write into the ROIs.
Similar problem lies in the following statement:
compOrigPart = frame;
That's a shallow copy, meaning it will just make compOrigPart
another reference to frame
(and therefore it will cease to be a ROI of compositeFrame
).
What you need is a deep copy, using copyTo
(note that the data types still need to match, but that was fixed earlier).
Finally, even though you try to be flexible regarding the type of the input video (judging by the vid.get(cv::CAP_PROP_FORMAT)
), the rest of the code really assumes that the input is 3 channel, and will break if it isn't.
At the least, there should be some assertion to cover this expectation.
Putting this all together:
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame, frame_gray, edges_gray;
cv::Mat compositeFrame;
cv::Mat compOrigPart, compBwPart, compEdgePart; // ROIs
while (vid.read(frame)) {
if (frame.empty()) break;
if (compositeFrame.empty()) {
// The rest of code assumes video to be BGR (i.e. 3 channel)
CV_Assert(frame.type() == CV_8UC3);
// Lazy initialize once we have the first frame
compositeFrame = cv::Mat(frame.rows, frame.cols * 3, frame.type());
compOrigPart = compositeFrame(cv::Range::all(), cv::Range(0, frame.cols));
compBwPart = compositeFrame(cv::Range::all(), cv::Range(frame.cols, frame.cols * 2));
compEdgePart = compositeFrame(cv::Range::all(), cv::Range(frame.cols * 2, frame.cols * 3));
}
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::Canny(frame_gray, edges_gray, 100, 150);
// Deep copy data to the ROI
frame.copyTo(compOrigPart);
// The ROI is BGR, so we need to convert back
cv::cvtColor(frame_gray, compBwPart, cv::COLOR_GRAY2BGR);
cv::cvtColor(edges_gray, compEdgePart, cv::COLOR_GRAY2BGR);
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Screenshot of the composite window (using some random test video off the web):
This is a combination of several issues.
The first problem is that you set the type of compositeFrame
to the value returned by vid.get(cv::CAP_PROP_FORMAT)
. Unfortunately that property doesn't seem entirely reliable -- I've just had it return 0 (meaning CV_8UC1
) after opening a color video, and then getting 3 channel (CV_8UC3
) frames. Since you want to have the compositeFrame
the same type as the input frame, this won't work.
To work around it, instead of using those properties, I'd lazy initialize compositeFrame
and the 3 ROIs after receiving the first frame (based on it's dimensions and type).
The next set of problems lies in those two statements:
cv::cvtColor(frame, compBwPart, cv::COLOR_BGR2GRAY);
cv::Canny(compBwPart, compEdgePart, 100, 150);
In this case assumption is made that frame
is BGR (since you're trying to convert), meaning compositeFrame
and its ROIs are also BGR. Unfortunately, in both cases you're writing a grayscale image into the ROI. This will cause a reallocation, and the target Mat
will cease to be a ROI.
To correct this, use temporary Mat
s for the grayscale data, and use cvtColor
to turn it back to BGR to write into the ROIs.
Similar problem lies in the following statement:
compOrigPart = frame;
That's a shallow copy, meaning it will just make compOrigPart
another reference to frame
(and therefore it will cease to be a ROI of compositeFrame
).
What you need is a deep copy, using copyTo
(note that the data types still need to match, but that was fixed earlier).
Finally, even though you try to be flexible regarding the type of the input video (judging by the vid.get(cv::CAP_PROP_FORMAT)
), the rest of the code really assumes that the input is 3 channel, and will break if it isn't.
At the least, there should be some assertion to cover this expectation.
Putting this all together:
#include <opencv2/opencv.hpp>
int main()
{
cv::VideoCapture vid("./Vid.avi");
if (!vid.isOpened()) return -1;
cv::Scalar fontColor(250, 250, 250);
cv::Point textPos(20, 20);
cv::Mat frame, frame_gray, edges_gray;
cv::Mat compositeFrame;
cv::Mat compOrigPart, compBwPart, compEdgePart; // ROIs
while (vid.read(frame)) {
if (frame.empty()) break;
if (compositeFrame.empty()) {
// The rest of code assumes video to be BGR (i.e. 3 channel)
CV_Assert(frame.type() == CV_8UC3);
// Lazy initialize once we have the first frame
compositeFrame = cv::Mat(frame.rows, frame.cols * 3, frame.type());
compOrigPart = compositeFrame(cv::Range::all(), cv::Range(0, frame.cols));
compBwPart = compositeFrame(cv::Range::all(), cv::Range(frame.cols, frame.cols * 2));
compEdgePart = compositeFrame(cv::Range::all(), cv::Range(frame.cols * 2, frame.cols * 3));
}
cv::cvtColor(frame, frame_gray, cv::COLOR_BGR2GRAY);
cv::Canny(frame_gray, edges_gray, 100, 150);
// Deep copy data to the ROI
frame.copyTo(compOrigPart);
// The ROI is BGR, so we need to convert back
cv::cvtColor(frame_gray, compBwPart, cv::COLOR_GRAY2BGR);
cv::cvtColor(edges_gray, compEdgePart, cv::COLOR_GRAY2BGR);
cv::putText(compOrigPart, "Original", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compBwPart, "GrayScale", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::putText(compEdgePart, "Canny edge detection", textPos, cv::FONT_HERSHEY_PLAIN, 1, fontColor);
cv::imshow("Composite of Original, BW and Canny frames", compositeFrame);
cv::imshow("Original", compOrigPart);
cv::imshow("BW", compBwPart);
cv::imshow("Canny", compEdgePart);
cv::waitKey(33);
}
}
Screenshot of the composite window (using some random test video off the web):
answered Jan 19 at 14:08
Dan MašekDan Mašek
8,90532647
8,90532647
Thanks. This seems to work, although I'm not sure why one can't rely onvid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.
– pusrob
Jan 21 at 17:10
add a comment |
Thanks. This seems to work, although I'm not sure why one can't rely onvid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.
– pusrob
Jan 21 at 17:10
Thanks. This seems to work, although I'm not sure why one can't rely on
vid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.– pusrob
Jan 21 at 17:10
Thanks. This seems to work, although I'm not sure why one can't rely on
vid.get(cv::CAP_PROP_FORMAT);
(mine returns 0 as well). Could you please modify your post with your version of OpenCV indicated somewhere? It could prove useful later.– pusrob
Jan 21 at 17:10
add a comment |
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f54245965%2fcvimshow-in-opencv-is-only-displaying-parts-of-a-composite-image-but-displayi%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Have you tried show the combined images using namedWindow( "Composite of Original, BW and Canny frames", WINDOW_AUTOSIZE ); ?
– gameon67
Jan 18 at 0:10
compOrigPart = frame
is a simple assignment of theMat
(which is kind of like a shared pointer). What you want is to copy the contents offrame
to the ROI represented bycompOrigPart
...– Dan Mašek
Jan 18 at 2:54
@gameon67 creating a namedWindow doesn't help a bit unfortunately, but thanks...
– pusrob
Jan 18 at 18:23
@DanMašek As I already described in point 1 of "These are the things I tried to overcome this issue: " section of the post, copying the contents of
frame
to the ROI doesn't help.– pusrob
Jan 18 at 18:26
I can only comment the code I see. The problem is likely a combination of multiple factors. Not copying is certainly not going to help, due to the reasons I already explained. It's hard to tell what data type
compositeFrame
uses, but I guess it's BGR, since you later convert frame from BGR to grayscale. However, you then assign the result of conversion to one of the ROIs.-- if the data types don't match a reallocation is done and it's no longer a ROI (but a new, independent, array).– Dan Mašek
Jan 19 at 13:08