源代码:http://pastebin.com/LyBbNCm6
网络摄像头的示例输出:
关于stackoverflow的第一篇文章,希望我做对了:
这个问题与C++ / OpenCV有关。
特别:
我正在尝试使用opencv的randu()和bitwise_xor()做等效于“一个时间片”的图像。我确实知道,针对此问题有更高性能的解决方案,不会遇到相同的图像质量下降和帧频问题。我还考虑了视频编解码器中的有损压缩可能遇到的问题。
对代码质量的道歉:
-这是概念代码的证明,因此,我没有做任何事情来使它成为面向对象的,也不利用任何机会将重复的代码转换为函数(对于造成可读性的影响,我事先表示歉意)。
-我试图逐行和逐节准确地注释各种代码块的预期目的。之所以有一些代码,是因为出于未知原因,尝试简化代码并更有效地利用内存是不成功的。
-我怀疑没有必要将颜色空间转换为HSV,但是我将这段代码从GPU加速的“inRange()”类型实现中遗留下来,目的是分割色相“红色”。
最终目标是使用随机噪声的未压缩视频作为共享密钥的对称密钥视频加密。这是我自己编写的编程练习。
我已经玩过AES(CBC),并且正在考虑为此目的对Mat进行序列化,但是我确实希望能够将加密的图像作为视频/图像数据(未压缩)进行查看。
从加密最佳实践和密钥管理的 Angular 来看,已建立代码库(如“OpenSSH”)中的非对称密钥方法可能是一个更好的决定(但这与我现在正在练习的编程实践是不同的)。例如:我考虑过通过SSH隧道传送libav / ffmpeg流。或VPN中的各种其他选项,以及查看OpenSSL。
在做事上很奇怪:
问题:
我实际上并不介意在“取消”窗口中可以看到的图像伪像。
题
我的问题实际上是关于“异或”的:
“xor”输出显然有偏差,表明bitwise_xor和mat类型的图像没有按照我的期望做。
如果我不得不猜测:我会说最大强度像素会在xor无法产生理想效果的地方产生偏差? 我不确定是否可以使用颜色深度或对垫型图像进行操作来获得所需的结果(不切实际的键管理,但作为安全的prng-是图像混淆)。
如果有OpenCV经验的人可以给我一些关于我可以使用哪些选项的指导,或者指出我忽略的内容,将不胜感激。
提前致谢,
布劳尔
源代码
#include <cv.hpp> //necessary because this code uses the OpenCV library
#include "/usr/local/include/opencv2/highgui/highgui.hpp" //necessary because this code uses the OpenCV library
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
// /* for the purpose of exiting via keyboard input////////////////////////////////////////////////
bool loop = true;
Size size(320,240);//the dst image size,e.g.100x100
// /* for the purpose of exiting via keyboard input////////////////////////////////////////////////
// /* storage(memory allocation) for images and data///////////////////////////////////////////////
Mat image, random;
// */ storage for images and data//////////////////////////////////////////////////////////////////
// /* declaration of char to hold input from the keyboard buffer///////////////////////////////////
char KeyStroke;
// */ declaration of char to hold input from the keyboard buffer///////////////////////////////////
//prepare image source/////////////////////////////////////////////////////////////////////////////
VideoCapture cap;//assigning camera and proportions
cap.open(0);//starting webcam feed
//prepare image source/////////////////////////////////////////////////////////////////////////////
/* video input specific////////////////////////////////////////////////////////////////////////////
//cap.set(3, 320);
//cap.set(4, 240);
//cap.set(5,5);
//cap.set(CV_CAP_PROP_FRAME_WIDTH,320);
//cap.set(CV_CAP_PROP_FRAME_HEIGHT,240);
*/// video input specific//////////////////////////////////////////////////////////////////////////
namedWindow("original",1);//creating window for unmodified image
namedWindow("random",1);//creating window for "random noise"
namedWindow("xor",1);//creating window for obfuscated output
namedWindow("unxor",1);//creating window for deobfuscated image
while(loop == true)
{
try
{
// /* //read "image" from webcam or video//////////////////////////////////////////////////////////
cap>>image;
// */ //read "image" from webcam or video//////////////////////////////////////////////////////////
// /* //generate Mat full of random noise//////////////////////////////////////////////////////////
random = Mat(240, 320, CV_8UC3);
randu(random, Scalar::all(0), Scalar::all(255));
// */ //generate Mat full of random noise//////////////////////////////////////////////////////////
// /* //resize image///////////////////////////////////////////////////////////////////////////////
resize(image,image,size);//resize image
// */ //resize image///////////////////////////////////////////////////////////////////////////////
// /* //recycled code//////////////////////////////////////////////////////////////////////////////
KeyStroke = cvWaitKey(100); //get keyboard input
if(KeyStroke==' '){
break;
}
// */ //recycled code//////////////////////////////////////////////////////////////////////////////
// /* //placeholder creation///////////////////////////////////////////////////////////////////////
Mat imageT, randomT, image2; //placeholders to preserve "image" and "random" in their original conditions for comparison
vector<Mat> channels; //bitwise_xor placeholder for "imageT"
vector<Mat> channels2; //bitwise_xor placeholder for "randomT"
vector<Mat> channels3; //bitwise_xor placeholder for "image2"
// */ //placeholder creation///////////////////////////////////////////////////////////////////////
// /* //prepare the input Mat(s) for bitwise_xor processing////////////////////////////////////////
cvtColor(image, imageT, CV_BGR2HSV);//cvtColor conversion of "image"(type: Mat) to HSV colorspace "imageT"(type: Mat)
cvtColor(random, randomT, CV_BGR2HSV);//cvtColor conversion of "random"(type: Mat) to HSV colorspace "randomT"(type: Mat)
cvtColor(image, image2, CV_BGR2HSV);//cvtColor conversion of "image"(type: Mat) to HSV colorspace "image2"(type: Mat)
// */ //prepare the input Mat(s) for bitwise_xor processing////////////////////////////////////////
// /* //prepare the necessary vector<mat> for adding the "random noise" to the output//////////////
split(imageT, channels);
Mat HueI(channels[0]); //Create "Hue" channel
Mat SatI(channels[1]); //Create "Sat" channel
Mat VeeI(channels[2]); //Create "Vee" channel
// */ //prepare the necessary vector<mat> for adding the "random noise" to the output//////////////
// /* //prepare the necessary vector<mat> for adding the "random noise" to the output//////////////
split(randomT, channels2);
Mat HueR(channels2[0]); //Create "Hue" channel
Mat SatR(channels2[1]); //Create "Sat" channel
Mat VeeR(channels2[2]); //Create "Vee" channel
// */ //prepare the necessary vector<mat> for adding the "random noise" to the output//////////////
// /* //prepare the necessary vector<mat> for holding the output from xor//////////////////////////
split(image2, channels3);
Mat Hue2(channels3[0]); //Create "Hue" channel
Mat Sat2(channels3[1]); //Create "Sat" channel
Mat Vee2(channels3[2]); //Create "Vee" channel
// */ //prepare the necessary vector<mat> for holding the output from xor//////////////////////////
// /* //xor "random noise" with the input mat to obfuscate the image from its original appearance//
bitwise_xor(HueI, HueR, Hue2);//xor "HueI"(type: Mat) from "channels[0]"(type: vector<Mat>)<-[composed of "imageT" split() output] with "HueR"(type: Mat)<-from "channels2[0]"(type: vector<Mat>)<-[composed of "randomT" split() output]
bitwise_xor(SatI, SatR, Sat2);//xor "SatI"(type: Mat) from "channels[0]"(type: vector<Mat>)<-[composed of "imageT" split() output] with "SatR"(type: Mat)<-from "channels2[1]"(type: vector<Mat>)<-[composed of "randomT" split() output]
bitwise_xor(VeeI, VeeR, Vee2);//xor "VeeI"(type: Mat) from "channels[0]"(type: vector<Mat>)<-[composed of "imageT" split() output] with "VeeR"(type: Mat)<-from "channels2[2]"(type: vector<Mat>)<-[composed of "randomT" split() output]
// */ //xor "random noise" with the input mat to obfuscate the image from its original appearance//
// /* //show the obfuscated output in window "xor"/////////////////////////////////////////////////
merge(channels3, image2);
cvtColor(image2, image2, CV_HSV2BGR);//GPU namespace cvtColor conversion of "oclImage"(type: Mat) to HSV colorspace "oclSrc_hsv"(type: Mat)
imshow("xor",image2);//show the obfuscated output in window "xor"
// */ //show the obfuscated output in window "xor"/////////////////////////////////////////////////
// /* //prepare the obfuscated output for removal of the "random noise"////////////////////////////
cvtColor(image2, image2, CV_BGR2HSV);//cvtColor conversion of "image2"(type: Mat) to HSV colorspace "image2"(type: Mat)
// */ //prepare the obfuscated output for removal of the "random noise"////////////////////////////
// /* //prepare the necessary vector<mat> for removing the "random noise" from the output//////////
split(image2, channels3);
Mat Hue3(channels3[0]); //Create "Hue" channel
Mat Sat3(channels3[1]); //Create "Sat" channel
Mat Vee3(channels3[2]); //Create "Vee" channel
// */ //prepare the necessary vector<mat> for removing the "random noise" from the output//////////
// /* //xor same "random noise" with the output mat to return the image to its original appearance/
bitwise_xor(Hue3, HueR, Hue3);//xor "Hue3"(type: Mat) from "channels3[0]"(type: vector<Mat>)<-[composed of "image2" split() output] with "HueR"(type: Mat)<-from "channels2[0]"(type: vector<Mat>)<-[composed of "randomT" split() output]
bitwise_xor(Sat3, SatR, Sat3);//xor "Sat3"(type: Mat) from "channels3[1]"(type: vector<Mat>)<-[composed of "image2" split() output] with "SatR"(type: Mat)<-from "channels2[1]"(type: vector<Mat>)<-[composed of "randomT" split() output]
bitwise_xor(Vee3, VeeR, Vee3);//xor "Vee3"(type: Mat) from "channels3[2]"(type: vector<Mat>)<-[composed of "image2" split() output] with "VeeR"(type: Mat)<-from "channels2[1]"(type: vector<Mat>)<-[composed of "randomT" split() output]
// /* //xor same "random noise" with the output mat to return the image to its original appearance/
// /* //show the deobfuscated output in window "unxor"/////////////////////////////////////////////
merge(channels3, image2); //recombine the 3x HSV Channels of "channel3"(type: vector<Mat>) into "image2"(type: Mat)
cvtColor(image2, image2, CV_HSV2BGR);//cvtColor conversion of "image2"(type: Mat) to BGR colorspace "image2"(type: Mat)
imshow("unxor",image2);//normal window show webcam or video
// */ //show the deobfuscated output in window "unxor"/////////////////////////////////////////////
// /* //show the original input in window "original" and "random noise" in window "random"/////////
cvtColor(imageT, image, CV_HSV2BGR);//cvtColor conversion of "randomT"(type: Mat) to BGR colorspace "random"(type: Mat)
cvtColor(randomT, random, CV_HSV2BGR);//cvtColor conversion of "randomT"(type: Mat) to BGR colorspace "random"(type: Mat)
imshow("original",image);//normal window show webcam or video
imshow("random",random);//normal window show webcam or video
// /* //show the original input in window "original" and "random noise" in window "random"/////////
}
// /* //recycled code//////////////////////////////////////////////////////////////////////////////
catch (Exception& e)//error checking
{
const char* err_msg = e.what();
std::cout << "exception caught: imshow:\n" << err_msg << std::endl;
}
char key = waitKey(33) & 0xFF;//checking for key press
if (key == 'q')//press q to quit
{
//cap.release();
image.release();
loop = false;
}
// */ //recycled code///////////////////////////////////////////////////////////////////
}
return 0;
}
最佳答案
http://imgur.com/6dI7nLd
我想我现在有一个可行的解决方案:
#include <cv.hpp>
#include "/usr/local/include/opencv2/highgui/highgui.hpp"
using namespace cv;
using namespace std;
int main(int argc, char* argv[])
{
bool loop = true;
Size size(320,240);
Mat image, image0, random;
char KeyStroke;
VideoCapture cap;
cap.open(0);
namedWindow("original",1);
namedWindow("random",1);
namedWindow("xor",1);
namedWindow("unxor",1);
while(loop == true)
{
try
{
cap>>image0;
random = Mat(240,320, CV_8UC3); //source: http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
randu(random, Scalar::all(0), Scalar::all(255)); //source: http://docs.opencv.org/doc/tutorials/core/mat_the_basic_image_container/mat_the_basic_image_container.html
imshow("random",random);
KeyStroke = cvWaitKey(100);
if(KeyStroke==' ')
{
break;
}
vector<Mat> channels0;
vector<Mat> channels1;
vector<Mat> channels2;
vector<Mat> channels3;
Mat imageT, imageD;
imageT = Mat::zeros(240,320, CV_8UC3);
imageD = Mat::zeros(240,320, CV_8UC3);
resize(image0,image0,size,CV_INTER_NN);
image = image0;
split(image, channels0);
Mat BlueI(channels0[0]);
Mat GreenI(channels0[1]);
Mat RedI(channels0[2]);
split(random, channels1);
Mat BlueR(channels1[0]);
Mat GreenR(channels1[1]);
Mat RedR(channels1[2]);
split(imageT, channels2);
Mat Blue2(channels2[0]);
Mat Green2(channels2[1]);
Mat Red2(channels2[2]);
split(imageD, channels3);
Mat Blue3(channels3[0]);
Mat Green3(channels3[1]);
Mat Red3(channels3[2]);
bitwise_xor(BlueI, BlueR, Blue2);
bitwise_xor(GreenI, GreenR, Green2);
bitwise_xor(RedI, RedR, Red2);
merge(channels2, imageT);
bitwise_xor(Blue2, BlueR, Blue3);
bitwise_xor(Green2, GreenR, Green3);
bitwise_xor(Red2, RedR, Red3);
merge(channels3, imageD);
merge(channels2, imageT);
merge(channels1, random);
merge(channels0, image);
imshow("original",image0);
resize(imageT,imageT,size, CV_INTER_NN);
imshow("xor",imageT);
resize(imageD,imageD,size, CV_INTER_NN);
imshow("unxor",imageD);
}
catch (Exception& e)
{
const char* err_msg = e.what();
std::cout << "exception caught: imshow:\n" << err_msg << std::endl;
}
char key = waitKey(33) & 0xFF;
if (key == 'q')
{
image.release();
loop = false;
}
}
return 0;
}
我认为是导致问题的HSV颜色空间。一旦我切换回使用BGR,一切都会开始正常工作。当我对随机噪声垫进行可视化时,我意识到有些麻烦,并且注意到3个通道中的2个的行为不符合预期。 http://docs.opencv.org/doc/tutorials/imgproc/histograms/histogram_calculation/histogram_calculation.html