Repository: opencv
Issue: warpAffine fails for images with more than 4 channels when borderValue specified with more than 4 channels
Labels: category: imgproc,Hackathon

<!--
If you have a question rather than reporting a bug please go to https://forum.opencv.org where you get much faster responses.
If you need further assistance please read [How To Contribute](https://github.com/opencv/opencv/wiki/How_to_contribute).

This is a template helping you to create an issue which can be processed as quickly as possible. This is the bug reporting section for the OpenCV library.
-->

##### System information (version)

This is with the opencv-python-headless wrapper

```
In [15]: cv2.__version__
Out[15]: '4.6.0'
```

- Operating System / Platform => Ubuntu 22.04


##### Detailed description

I'm using cv2.warpAffine on images with large numbers of channels, which works by default. However, I need to specify a custom borderValue of nan, so I know where observed data exists and where it doesn't. I could warp a mask or break it up into separate channels, but simply allowing borderValue to have as many values as there are channels seems like a better solution.

##### Steps to reproduce

```python
import numpy as np
import cv2

flags = cv2.INTER_LINEAR
borderMode = cv2.BORDER_CONSTANT
# borderValue = np.nan
borderValue = (np.nan, np.nan, np.nan, np.nan, np.nan)

img = np.random.rand(32, 32, 5)
M = np.array([[ 0.92387953, -0.38268343,  0.        ],
              [ 0.38268343,  0.92387953,  0.        ],
              [ 0.        ,  0.        ,  1.        ]])
dsize = (img.shape[1], img.shape[0])

warped = cv2.warpAffine(img, M[0:2], dsize=dsize, flags=flags,
                        borderMode=borderMode, borderValue=borderValue)
```

Results in:

```
error: OpenCV(4.6.0) :-1: error: (-5:Bad argument) in function 'warpAffine'
> Overload resolution failed:
>  - Scalar value for argument 'borderValue' is longer than 4
>  - Scalar value for argument 'borderValue' is longer than 4
```


And again, when there are only 3 dims, this does work correctly:

```python
import numpy as np
import cv2

flags = cv2.INTER_LINEAR
borderMode = cv2.BORDER_CONSTANT
# borderValue = np.nan
borderValue = (np.nan, np.nan, np.nan)

img = np.random.rand(32, 32, 3)
M = np.array([[ 0.92387953, -0.38268343,  0.        ],
              [ 0.38268343,  0.92387953,  0.        ],
              [ 0.        ,  0.        ,  1.        ]])
dsize = (img.shape[1], img.shape[0])

warped = cv2.warpAffine(img, M[0:2], dsize=dsize, flags=flags,
                        borderMode=borderMode, borderValue=borderValue)


import kwimage
warped_canvas = kwimage.fill_nans_with_checkers(warped)
import kwplot
kwplot.autompl()
kwplot.imshow(img, fnum=1, pnum=(1, 2, 1))
kwplot.imshow(warped_canvas, fnum=1, pnum=(1, 2, 2))
```

![image](https://user-images.githubusercontent.com/3186211/180360597-a2782d86-889f-422a-9f1a-ae8059cf2617.png)


Note, the other odd thing that happens, is if you just specify the borderValue as a scalar, it only applies to the first channel, and the rest are zeroed. It seems like the scalar should be applied to all channels. 


```python
import numpy as np
import cv2

flags = cv2.INTER_LINEAR
borderMode = cv2.BORDER_CONSTANT
borderValue = np.nan
# borderValue = (np.nan, np.nan, np.nan)

img = np.random.rand(32, 32, 3)
M = np.array([[ 0.92387953, -0.38268343,  0.        ],
              [ 0.38268343,  0.92387953,  0.        ],
              [ 0.        ,  0.        ,  1.        ]])
dsize = (img.shape[1], img.shape[0])

warped = cv2.warpAffine(img, M[0:2], dsize=dsize, flags=flags,
                        borderMode=borderMode, borderValue=borderValue)


import kwimage
warped_canvas = kwimage.fill_nans_with_checkers(warped)
import kwplot
kwplot.autompl()
kwplot.imshow(img, fnum=1, pnum=(1, 2, 1))
kwplot.imshow(warped_canvas, fnum=1, pnum=(1, 2, 2))
```

![image](https://user-images.githubusercontent.com/3186211/180360734-f68332f1-f047-4acc-9915-e77469a10128.png)

I'd be happy with either fix:

* allow borderValue to accept as many values as there are channels
* if borderValue is a scalar use its value for all channels, not just the first.