문제 설명
rgba() 메서드에서 반환된 이 Mat가 RGBA 형식이 아닌 BGR 형식으로 나타나는 이유는 무엇입니까? (Why does this Mat returned by rgba() method appear to have BGR format rather than RGBA format?)
여러 곳에서 읽었습니다(출처 , 소스) OpenCV는 기본적으로 BGR 색상 형식을 사용합니다.
하지만 이미지에서 특정 색상(빨간색)의 얼룩을 감지하는 클래스를 작성 중입니다(색상 얼룩 감지 샘플). 따라서 onCameraFrame(CvCameraViewFrame inputFrame)
함수에서 inputFrame.rgba()<값을 반환합니다. /코드>. 문서에 따르면 a>,
rgba() 이 메서드는 프레임이 있는 RGBA Mat를 반환합니다.
그래서 내 rgbaFrame 내 프로그램에서 inputFrame.rgba()
의 값을 저장하는 변수인
에는 RGBA 형식의 Mat가 포함되어 있습니다.
하지만 앱을 실행하면 원본 이미지의 빨간색은 외부 SD 카드에 쓴 rgbaFrame
Mat에서 파란색으로 나타납니다. 빨간색이 파란색으로 보이기 때문에 매트가 BGR 형식인 것 같습니다. (이 내용은 이 질문에 대한 의견입니다.)
그래서 cvtColor
함수를
Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_RGB2HSV_FULL);
에서
6Imgproc.cvtColor(rgbaFrame, hsvImage, Imgproc.COLOR_BGR2HSV_FULL);
로 변경했습니다. 하지만 프로그램을 실행할 때 아무것도 변경되지 않았습니다. 원본 이미지의 빨간색은 캡처된 프레임에서 여전히 파란색으로 나타납니다.
이제 RGB를 BGR 형식으로 변환하여 문제를 해결하는 데 도움이 되는지 확인하는 방법을 찾고 있습니다. 그러나 하나를 찾지 못했습니다. BGR을 RGB로 변환하려면 어떻게 해야 하나요? 다른 제안 사항이 있으면 공유해 주세요.
-
참조 솔루션
방법 1:
OpenCV uses BGR by default, however, Android frame.rgba()
implementation returns RGB (possibly for compliance with imageview and other Android components). However, the OpenCV function imwrite
still requires BGR, therefore if you save the image without first converting it to BGR then the blue and red channels are saved incorrectly (swapped), because the Mat file of the frame has red channel in index 0 (RGB) whereas imwrite
writes index 0 as blue (BGR). Similarly the frame has blue channel in index 2 whereas imwrite
writes index 2 as red. You can call cvtcolor
with COLOR_RGB2BGR
before saving to a file.
/**
* Callback method that is called on every frame of the CameraBridgeViewBase class of OpenCV
*/
override fun onCameraFrame(inputFrame: CameraBridgeViewBase.CvCameraViewFrame?): Mat {
inputFrame?.let { currentFrame ‑>
val currentFrameMat = currentFrame.rgba()
// save the RGB2BGR converted version
val convertedMat = Mat()
Imgproc.cvtColor(currentFrameMat, convertedMat, Imgproc.COLOR_RGB2BGR)
Imgcodecs.imwrite(imageFilePath, convertedMat)
return currentFrameMat
}
return Mat()
}
참조 문서