任何人都可以幫助我解決這個問題,如何在不使用內置翻頁功能的情況下翻轉圖像,即使用OpenCV在C++中翻轉(src圖像,目標圖像,1或0)。我對這個軟件很陌生,所以請幫忙。如何在OpenCV中不使用內置函數翻轉來翻轉?
0
A
回答
0
假設你有一個很好的理由不使用OpenCV的flip功能,您可以編寫自定義之一。
對於此示例,我將使用CV_8UC3
圖像。最後我會指出如何將其擴展到不同的格式。
讓我們先看看如何翻轉圖像x軸,這對應於cv::flip(src, dst, 1)
。給定一個src
圖像,dst
圖像將具有相同的y
座標,並且x
座標爲src.cols - 1 - x
座標。在實踐中:
void flip_lr(const Mat3b& src, Mat3b& dst)
{
Mat3b _dst(src.rows, src.cols);
for (int r = 0; r < _dst.rows; ++r) {
for (int c = 0; c < _dst.cols; ++c) {
_dst(r, c) = src(r, src.cols - 1 - c);
}
}
dst = _dst;
}
然後,以翻轉左右(對應於cv::flip(src, dst, 0)
)y軸dst
將具有相同的座標x
,並y
爲src.rows - 1 - y
。但是,您可以重複使用上述功能,只需調整dst
矩陣,在x軸上應用翻轉,然後轉回。在實踐中:
dst = src.t();
flip_lr(dst, dst);
dst = dst.t();
然後翻轉兩個軸,對應於cv::flip(src, dst, -1)
,你需要簡單的翻蓋上的X和Y軸的結合:
flip_lr(src, dst);
dst = dst.t();
flip_lr(dst, dst);
dst = dst.t();
您可以在自定義的翻蓋包裝這個功能函數採用相同的參數cv::flip
:
void custom_flip(const Mat3b& src, Mat3b& dst, int code)
{
if (code > 0)
{ // Flip x axis
flip_lr(src, dst);
}
else if (code == 0)
{
// Flip y axis
dst = src.t();
flip_lr(dst, dst);
dst = dst.t();
}
else // code < 0
{
// Flip x and y axis
flip_lr(src, dst);
dst = dst.t();
flip_lr(dst, dst);
dst = dst.t();
}
}
注意,您可以適應這種不同的格式簡單地對矯正的flip_lr
功能,並小心調用custom_flip
內的相應版本,現在將接受Mat
而不是Mat3b
。
參考全碼:
void flip_lr(const Mat3b& src, Mat3b& dst)
{
Mat3b _dst(src.rows, src.cols);
for (int r = 0; r < _dst.rows; ++r) {
for (int c = 0; c < _dst.cols; ++c) {
_dst(r, c) = src(r, src.cols - 1 - c);
}
}
dst = _dst;
}
void custom_flip(const Mat3b& src, Mat3b& dst, int code)
{
if (code > 0)
{ // Flip x axis
flip_lr(src, dst);
}
else if (code == 0)
{
// Flip y axis
dst = src.t();
flip_lr(dst, dst);
dst = dst.t();
}
else // code < 0
{
// Flip x and y axis
flip_lr(src, dst);
dst = dst.t();
flip_lr(dst, dst);
dst = dst.t();
}
}
int main(void)
{
Mat3b img = imread("path_to_image");
Mat3b flipped;
flip(img, flipped, -1);
Mat3b custom;
custom_flip(img, custom, -1);
imshow("OpenCV flip", flipped);
imshow("Custom flip", custom);
waitKey();
return 0;
}
1
OpenCV的翻轉功能使用內部flipHoriz or flipVert函數。
static void
flipHoriz(const uchar* src, size_t sstep, uchar* dst, size_t dstep, Size size, size_t esz)
{
int i, j, limit = (int)(((size.width + 1)/2)*esz);
AutoBuffer<int> _tab(size.width*esz);
int* tab = _tab;
for(i = 0; i < size.width; i++)
for(size_t k = 0; k < esz; k++)
tab[i*esz + k] = (int)((size.width - i - 1)*esz + k);
for(; size.height--; src += sstep, dst += dstep)
{
for(i = 0; i < limit; i++)
{
j = tab[i];
uchar t0 = src[i], t1 = src[j];
dst[i] = t1; dst[j] = t0;
}
}
}
static void
flipVert(const uchar* src0, size_t sstep, uchar* dst0, size_t dstep, Size size, size_t esz)
{
const uchar* src1 = src0 + (size.height - 1)*sstep;
uchar* dst1 = dst0 + (size.height - 1)*dstep;
size.width *= (int)esz;
for(int y = 0; y < (size.height + 1)/2; y++, src0 += sstep, src1 -= sstep,
dst0 += dstep, dst1 -= dstep)
{
int i = 0;
if(((size_t)src0|(size_t)dst0|(size_t)src1|(size_t)dst1) % sizeof(int) == 0)
{
for(; i <= size.width - 16; i += 16)
{
int t0 = ((int*)(src0 + i))[0];
int t1 = ((int*)(src1 + i))[0];
((int*)(dst0 + i))[0] = t1;
((int*)(dst1 + i))[0] = t0;
t0 = ((int*)(src0 + i))[1];
t1 = ((int*)(src1 + i))[1];
((int*)(dst0 + i))[1] = t1;
((int*)(dst1 + i))[1] = t0;
t0 = ((int*)(src0 + i))[2];
t1 = ((int*)(src1 + i))[2];
((int*)(dst0 + i))[2] = t1;
((int*)(dst1 + i))[2] = t0;
t0 = ((int*)(src0 + i))[3];
t1 = ((int*)(src1 + i))[3];
((int*)(dst0 + i))[3] = t1;
((int*)(dst1 + i))[3] = t0;
}
for(; i <= size.width - 4; i += 4)
{
int t0 = ((int*)(src0 + i))[0];
int t1 = ((int*)(src1 + i))[0];
((int*)(dst0 + i))[0] = t1;
((int*)(dst1 + i))[0] = t0;
}
}
for(; i < size.width; i++)
{
uchar t0 = src0[i];
uchar t1 = src1[i];
dst0[i] = t1;
dst1[i] = t0;
}
}
}
//你可以用一個小的修改使用如下
void myflip(InputArray _src, OutputArray _dst, int flip_mode)
{
CV_Assert(_src.dims() <= 2);
Size size = _src.size();
if (flip_mode < 0)
{
if (size.width == 1)
flip_mode = 0;
if (size.height == 1)
flip_mode = 1;
}
if ((size.width == 1 && flip_mode > 0) ||
(size.height == 1 && flip_mode == 0) ||
(size.height == 1 && size.width == 1 && flip_mode < 0))
{
return _src.copyTo(_dst);
}
Mat src = _src.getMat();
int type = src.type();
_dst.create(size, type);
Mat dst = _dst.getMat();
size_t esz = CV_ELEM_SIZE(type);
if(flip_mode <= 0)
flipVert(src.ptr(), src.step, dst.ptr(), dst.step, src.size(), esz);
else
flipHoriz(src.ptr(), src.step, dst.ptr(), dst.step, src.size(), esz);
if(flip_mode < 0)
flipHoriz(dst.ptr(), dst.step, dst.ptr(), dst.step, dst.size(), esz);
}
相關問題
- 1. 如何通過翻轉數組來翻轉多邊形?
- 2. 翻轉時翻轉表格行內容
- 3. numpy opencv翻轉行的設置
- 4. 如何使用vtk旋轉/翻譯/翻轉vtkActor2D對象?
- 5. jQuery的翻轉電平不翻轉
- 6. Ractive.js翻轉布爾函數
- 7. 如何在.NET中翻轉/旋轉PrintDocument?
- 8. 翻轉新內容
- 9. 翻轉使用SkiaSharp
- 10. Viewflipper不翻轉
- 11. CCSprite不翻轉
- 12. 翻譯轉:SVG不是圍繞中心旋轉,即使翻譯:
- 13. 使用OpenCV翻譯和旋轉圖像使用OpenCV
- 14. 如何翻轉單個UIView(不翻轉父視圖)
- 15. 如何翻轉jcombobox?
- 16. 如何翻轉flash.media.Video?
- 17. 如何翻轉QImage
- 18. 如何翻轉UIImageView?
- 19. 在sql中翻轉數據
- 20. 翻轉參數榆樹函數調用
- 21. opencv庫中的水平翻轉
- 22. 在IE翻轉動畫:翻轉側顯示鏡像內容
- 23. 無限滾動翻轉Flipview在翻轉時更新內容
- 24. SVG矩陣:不同的翻轉,旋轉和翻轉PLUS旋轉
- 25. 在ViewPager中翻轉?
- 26. 如何翻轉中的R
- 27. SR翻轉翻牌和D翻轉翻牌
- 28. 翻轉PostgreSQL中
- 29. 如何在翻頁前後翻轉翻頁書本
- 30. 翻轉
爲什麼你不希望使用內置的功能呢? – DaBrain
剛剛被卡住了,想要做很多努力工作:D – shanu