ermig1979 / Simd

C++ image processing and machine learning library with using of SIMD: SSE, AVX, AVX-512, AMX for x86/x64, VMX(Altivec) and VSX(Power7) for PowerPC, NEON for ARM.
http://ermig1979.github.io/Simd
MIT License
2.04k stars 407 forks source link

sub yuv420 region convert rgb image issuses #136

Closed w136111526 closed 3 years ago

w136111526 commented 3 years ago

Hello, I want to use SIMD Yuv420 sub-region image and converted to rgb image data, but the image display texture is not normal, what is the problem with my code: std::ifstream ifs("e:/1280x720.yuv", std::ios::binary); ifs.seekg(0, std::ios::end); int nlen = ifs.tellg();//yuv420p:1280x720x3/2 unsigned char data = new unsigned char[nlen]; ifs.seekg(0, ios::beg); ifs.read((char)data, nlen); ifs.close(); unsigned char ptr = data; Frame frame(1280, 720, Frame::Yuv420p, ptr, 1280, ptr + graySize, 640, ptr + graySize 5 / 4, 640); Frame subFrameRegion = frame.Region(300, 100, 800, 500); Frame rgbFrame(500, 400, Frame::Bgr24); DWORD dTime = GetTickCount(); Convert(subFrameRegion, rgbFrame); cv::Mat matResult(400, 500, CV_8UC3, rgbFrame.planes[0].data); cv::imshow("test", matResult); cv::waitKey(0); delete[] data;

image

ermig1979 commented 3 years ago

Try to use

cv::Mat matResult(400, 500, CV_8UC3, rgbFrame.planes[0].data, rgbFrame.planes[0].stride);

instead of

cv::Mat matResult(400, 500, CV_8UC3, rgbFrame.planes[0].data);
w136111526 commented 3 years ago

It looks like the Roi region of the image is normal, but there is a small problem. If I choose a region that is too small (less than 100 widths) , the image transcoding will only be partially normal and the right one will not be displayed: std::ifstream ifs("e:/1280x720.yuv", std::ios::binary); ifs.seekg(0, std::ios::end); int nlen = ifs.tellg();//yuv420p:1280x720x3/2 unsigned char data = new unsigned char[nlen]; ifs.seekg(0, ios::beg); ifs.read((char)data, nlen); ifs.close(); unsigned char ptr = data; Frame frame(1280, 720, Frame::Yuv420p, ptr, 1280, ptr + graySize, 640, ptr + graySize 5 / 4, 640); Frame subFrameRegion = frame.Region(200, 400, 250, 520); Frame rgbFrame(50, 120, Frame::Bgr24); DWORD dTime = GetTickCount(); Convert(subFrameRegion, rgbFrame); cv::Mat matResult(120, 50, CV_8UC3, rgbFrame.planes[0].data, rgbFrame.planes[0].stride); cv::imshow("test", matResult); cv::waitKey(0); delete[] data; image

ermig1979 commented 3 years ago

1) Function 'Convert' converts only frames with the same size. 2) Could you confuse width and height here: Frame rgbFrame(50, 120, Frame::Bgr24); cv::Mat matResult(120, 50, CV_8UC3, rgbFrame.planes[0].data, rgbFrame.planes[0].stride);