[英]Convert color channels from BGR to RGB
我正在使用OpenCV进行视频捕获项目。 我已经能够使视频捕获正常工作,但是我想将摄像机滤镜更改为“常规”光谱,以便香蕉不是蓝色的,而是黄色的。 这就是RGB光谱。 我在for循环中的程序中进行了转换,但相机视图仍然是BRG。 这是一张图片。
如何获得显示“真实”颜色的图像视图? 这是我的代码。
垫到图像类
import java.awt.Color;
import java.awt.image.BufferedImage;
import org.opencv.core.Core;
import org.opencv.core.Mat;
public class Mat2Image {
Mat mat = new Mat();
private int argb = 0;
Color c = new Color(argb, true);
BufferedImage img;
byte [] dat;
Mat2Image(){
}
public Mat2Image(Mat mat) {
getSpace(mat);
}
public void getSpace(Mat mat) {
this.mat = mat;
int w = mat.cols(), h = mat.rows();
if (dat == null || dat.length != w * h * 3)
dat = new byte[w * h * 3];
if (img == null || img.getWidth() != w || img.getHeight() != h || img.getType() != BufferedImage.TYPE_3BYTE_BGR)
img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
int[] holder = new int[w * h];
holder = img.getData().getPixels(0, 0, w, h, (int[]) null);
for (int i = 0; i < dat.length; i++) {
int blueChannel = (holder[i] & 0xFF0000) >> 4;
int greenChannel = (holder[i] & 0xFF00) >> 2;
int redChannel = (holder[i] & 0xFF);
int rgb = (blueChannel) & (greenChannel << 2) & (redChannel << 4);
dat[i] = (byte) rgb;
}
}
BufferedImage getImage(Mat mat) {
getSpace(mat);
mat.get(0, 0, dat);
img.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), dat);
return img;
}
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
}
视频拍摄类
public class VideoCap {
static {
System.loadLibrary(Core.NATIVE_LIBRARY_NAME);
}
int currFrame = 0;
VideoCapture cap;
Mat2Image mat2Img = new Mat2Image();
VideoCap() {
cap = new VideoCapture();
cap.open(0);
}
BufferedImage getOneFrame() {
currFrame++;
//currFrame is just to stop the camera of after the running for a bit.
if (currFrame == 20) {
cap.read(mat2Img.mat);
System.exit(0);
}
cap.read(mat2Img.mat);
return mat2Img.getImage(mat2Img.mat);
}
}
我的JFrame类
public class MyFrame extends JFrame {
private JPanel contentPane;
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
MyFrame frame = new MyFrame();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100,100,650,490);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5,5,5,5));
setContentPane(contentPane);
contentPane.setLayout(null);
new MyThread().start();
}
VideoCap videoCap = new VideoCap();
public void paint(Graphics g){
g = contentPane.getGraphics();
g.drawImage(videoCap.getOneFrame(), 0, 0, this);
}
class MyThread extends Thread{
@Override
public void run() {
for (;;){
repaint();
try { Thread.sleep(30);
} catch (InterruptedException e) { }
}
}
}
}
您正在对颜色进行错误的重新排列-您的移位不够大,应该使用OR( |
)而不是AND( &
)运算符来重新组合颜色。
您的代码:
int blueChannel = (holder[i] & 0xFF0000) >> 4;
int greenChannel = (holder[i] & 0xFF00) >> 2;
int redChannel = (holder[i] & 0xFF);
int rgb = (blueChannel) & (greenChannel << 2) & (redChannel << 4);
应该变成:
int blueChannel = (holder[i] & 0xFF0000) >> 16;
int greenChannel = (holder[i] & 0xFF00) >> 8;
int redChannel = (holder[i] & 0xFF);
int rgb = (blueChannel) | (greenChannel << 8) | (redChannel << 16);
编辑
此外,看起来您没有在目标图像上使用int[]
,而是在颜色上使用了3字节的编码。 因此,您更有可能需要执行以下操作:
for (int i = 0; i < holder.length; i++) {
byte blueChannel = (byte) ((holder[i] & 0xFF0000) >> 16);
byte greenChannel = (byte) ((holder[i] & 0xFF00) >> 8);
byte redChannel = (byte) (holder[i] & 0xFF);
dat[i*3] = redChannel;
dat[i*3+1] = greenChannel;
dat[i*3+2] = blueChannel;
但是对于我来说,现在还不清楚是从BGR变为RGB,还是从RGB变为BGR。 您可能需要更改最后3个作业的顺序才能正确执行此操作。
昨天我花了一些时间试图将其分解,最终使它起作用。 我要做的第一件事是分配新图像。 这是在getSpace
完成的。 然后,我转换分配的图像,然后从矩阵中捕获数据,然后将数据放入图像中。 最后3个步骤全部在getImage
。 这是我解决的方法。
public void getSpace(Mat mat) {
this.mat = mat;
int w = mat.cols(), h = mat.rows();
if (dat == null || dat.length != w * h * 3)
dat = new byte[w * h * 3];
if (img == null || img.getWidth() != w || img.getHeight() != h || img.getType() != BufferedImage.TYPE_3BYTE_BGR)
img = new BufferedImage(w, h, BufferedImage.TYPE_3BYTE_BGR);
}
BufferedImage getImage(Mat mat) {
getSpace(mat);
mat.get(0, 0, dat);
for (int i = 0; i < dat.length; i+= 3) {
byte redChannel = dat[i];
byte blueChannel = dat[i+2];
dat[i] = blueChannel;
dat[i+2] = redChannel;
}
img.getRaster().setDataElements(0, 0, mat.cols(), mat.rows(), dat);
return img;
}
Mat2Image类的其余代码应与我未在答案中添加的代码相同,您可以尝试一下。 :)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.