When I take an image using OpenCV that is larger than 4000 pixels wide, using a high quality picam, the image data appears corrupted (it's offset).
As stated, I cannot get a good image when using OpenCV at over 4000 pixels wide of resolution. I know that the hardware is not the issue as I can get a clean full resolution (4056x3040) image when I use the raspistill command:
sudo raspistill -o testing.tiff -w 4056 -h 3040
Here is the clean output from raspistill:
4056x3040 image - Clean Image produced by raspistill command
I am able to capture images using OpenCV in either Python:
import cv2 as cv
def main():
cap = cv.VideoCapture("/dev/video2", cv.CAP_V4L2)
cap.set(cv.CAP_PROP_FRAME_WIDTH, 4056)#works fine up to 4000
cap.set(cv.CAP_PROP_FRAME_HEIGHT, 3040)
if not(cap.isOpened()):
print("could not open video device")
else:
print("cap opened")
ret, frame = cap.read()
if(ret):
cv.imwrite("./test_im.jpg", frame)
print("image saved")
else:
print("no capture data returned")
if __name__ == "__main__":
main()
Or I can capture in OpenCV with C++:
#include <opencv2/opencv.hpp>
#include <iostream>
int main(int argc, char *argv[]){
cv::Mat frame;
cv::VideoCapture cap("/dev/video2", cv::CAP_V4L2);
cap.set(cv::CAP_PROP_FRAME_WIDTH, 4056);
cap.set(cv::CAP_PROP_FRAME_HEIGHT, 3040);
if(cap.isOpened() == false){
std::cout << "cap not opened" << std::endl;
}
else{
std::cout << "cap opened" << std::endl;
}
cap >> frame;
if(frame.empty()){
std::cout << "empy frame";
}
else{
std::cout << "successfully captured image" << std::endl;
cv::imwrite("test.tiff", frame);
}
}
The Result is the same either way.
Here is the corrupted output from OpenCV:
4056x3040 image - Corrupted and captured by OpenCV
To me it seems as if it something was going wrong with the timing of the capture. The format of which I save it to does not make a difference either. I have tried .png, .jpg, and .tiff. The result is always the same. After reboot the results remain the same.
If I reduce the desired capture resolution to only 4000x3040 then I am able to successfully make a capture. Here are the results:
4000x3040 image - successfully captured by OpenCV
I am not sure why this is happening. And would really appreciate any help! Let me know if there is any other information that could be useful!
I determined that the issue was related to a necessary buffer required by the Raspberry Pi and OpenCV. I believe it is related to this answer on stack overflow.
As a result, I was able to fix the image streaking by reducing the resolution that I was requesting to be a multiple of 32 in both length and width e.g. 4032x3040 (instead of 4056x3040). This allowed me to get almost full resolution images, and was sufficient for the task. I was unable to figure out how I would be able to get a full resolution image using OpenCV and a High Quality Raspicam.