Access pixels with Mat OpenCV - c++

I would like to access pixels in RGB with OpenCV 2.3.
I'm trying like this but it's like every pixels are equal frame after frame because I got no output. Images are from my webcam and I can see them.
Btw RED = 0;
THX
Mat frame;
Mat oldFrame;
VideoCapture cap(0);
cap >> oldFrame;
sumFramePix = oldFrame.cols * oldFrame.rows;
nbChannels = oldFrame.channels();
cout << "NbcHANNELs : " << nbChannels << endl;
imshow("Video 1", oldFrame);
while(1)
{
cap >> frame;
imshow("Video 1", frame);
for(int i=0; i<frame.rows; i++)
{
for(int j=0; j<frame.cols; j++)
{
if (frame.ptr<uchar>(i)[nbChannels*j+RED] < oldFrame.ptr<uchar>(i)[nbChannels*j+RED])
{
cout << "==============-";
}
}
}
oldFrame = frame;
if(waitKey(300) >= 0) break;
}

Change
oldFrame = frame;
to
oldFrame = frame.clone();
You are creating two Mat objects that point to the same data. clone() makes a deep copy.

Related

Find yaw, roll and pitch angles of the face from live webcam stream

I need to find the yaw, roll and pitch angles from a webcam stream of a face. I used opencv to get face landmarks and detect the face. Can someone help or guide me on how to find and print those angles?
I am using Visual Studio 2022 (community).
Ptr<Facemark> facemark; //mark detection
CascadeClassifier faceDetector; //face detection
void process(Mat img, Mat imgcol) {
vector<Rect> faces;
faceDetector.detectMultiScale(img, faces);
Mat imFace;
if (faces.size() != 0) {
for (size_t i = 0; i < faces.size(); i++)
{
cv::rectangle(imgcol, faces[i], Scalar(255, 0, 0));
imFace = imgcol(faces[i]);
resize(imFace, imFace, Size(imFace.cols * 5, imFace.rows * 5));
faces[i] = Rect(faces[i].x = 0, faces[i].y = 0, faces[i].width * 5,
(faces[i].height) * 5);
}
vector< vector<Point2f> > shapes;
if (facemark->fit(imFace, faces, shapes))
{
for (unsigned long i = 0; i < faces.size(); i++) {
for (unsigned long k = 0; k < shapes[i].size(); k++) {
cv::circle(imFace, shapes[i][k], 5, cv::Scalar(0, 0, 255),FILLED);
}
}
}
namedWindow("Detected_shape");
imshow("Detected_shape", imFace);
waitKey(5);
}
else {
cout << "Faces not detected." << endl;
}
}
int main()
{
facemark = FacemarkLBF::create();
facemark->loadModel("lbfmodel.yml");
faceDetector.load("D:/opencv/build/install/etc/haarcascades/haarcascade_frontalface_alt2.xml");
cout << "Loaded model" << endl;
VideoCapture cap(1); //capture image
int initialized = 0;
for (;;)
{
if (!cap.isOpened()) {
cout << "Video Capture Fail" << endl;
break;
}
else {
Mat img; //image containers
Mat imgbw;
cap >> img; //image from webcam
resize(img, img, Size(460, 460), 0, 0, INTER_LINEAR_EXACT);
cvtColor(img, imgbw, COLOR_BGR2GRAY);
process(imgbw, img);
namedWindow("Live", WINDOW_AUTOSIZE);
imshow("Live", img);
waitKey(5);
}
}
}
The code includes what I could do so far. It detects a face and landmarks. How do I find the angles and print them from this?

Open cv Error : Assertion failed (IIR filter on video frames)

in below code i want to apply temp_rec filter on movies frame.
But i got the error assertion failed.
with video_line_extractor function extract a time series of pixels in a row
then in the main i apply my temporal filter to all of the row of the image.
I know it is a inefficient native code but i can not use of opencv internal
function instead of my temp_rec function.
int width_frame, heigth_frame, num_frames;
VideoCapture cap;
void temp_rec(float* in, float* out, int w, float tau) {
float yp;
float tauo = 1 / tau;
for (int i = 0; i<w;i++) {
if (i == 0) {
*out = tauo*(*in);
}
else {
out -= 1;
yp = *(out);
out += 1;
*(out) = tauo*(*(in)) + ((exp(-tauo))*yp);
}
out += 1;
in += 1;//prepare for calculate next element
}
}
Mat video_line_extractor(int whichrow) {//extract a row of frames
// Create a VideoCapture object and open the input file
// If the input is the web camera, pass 0 instead of the video file name
cap = VideoCapture("a valid path");
int frame_counter = 0;
Mat M_temp = Mat::eye(width_frame, num_frames, CV_8UC3);
// Check if camera opened successfully
if (!cap.isOpened()) {
cout << "Error opening video stream or file :(" << endl;
}
while (frame_counter<num_frames) {
Mat frame;
// Capture frame-by-frame
cap >> frame;
// If the frame is empty, break immediately
if (frame.empty())
break;
cvtColor(frame, frame, CV_BGR2GRAY);
for(int j=0;j<width_frame;j++) //we in above first extract a movie frame that as we know it is a image
//in this 'for' we extract that row data with a pointer to one of the row in th M_temp
M_temp.at<uchar>(frame_counter , j) = frame.ptr<uchar>(whichrow)[j];
frame_counter++;
}
// When everything done, release the video capture object
cap.release();
return M_temp;
}
int main() {
cap=VideoCapture("a valid path");
width_frame = cap.get(CV_CAP_PROP_FRAME_WIDTH);
heigth_frame = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
num_frames = cap.get(CV_CAP_PROP_FRAME_COUNT);
Mat image= Mat::zeros(width_frame, num_frames, CV_8UC3);//initalize input
Mat image_o = Mat::zeros(width_frame, num_frames, CV_8UC3);//initialize output
for (int jj = 0;jj < heigth_frame;jj++) {
image = video_line_extractor(jj);
for (int j = 0;j < width_frame;j++)
temp_rec((float *)image.ptr<uchar>(j), (float *)image_o.ptr<uchar>(j), num_frames, 10);
}
imshow("Image", image);
waitKey(0);
return 0;
}
edit: assertion error
https://i.stack.imgur.com/BGGu0.png
int width_frame, heigth_frame, num_frames;
VideoCapture cap;
void temp_rec(float* in, float* out, int w, float tau) {
float yp;
float tauo = 1 / tau;
for (int i = 0; i<w;i++) {
if (i == 0) {
*out = tauo*(*in);
}
else {
out -= 1;
yp = *(out);
out += 1;
*(out) = tauo*(*(in)) + ((exp(-tauo))*yp);
}
out += 1;
in += 1;//prepare for calculate next element
}
}
Mat video_line_extractor(int whichrow) {//extract a row of frames
// Create a VideoCapture object and open the input file
// If the input is the web camera, pass 0 instead of the video file name
cap = VideoCapture("a valid path");
int frame_counter = 0;
Mat M_temp = Mat::eye(width_frame, num_frames, CV_8UC3);
// Check if camera opened successfully
if (!cap.isOpened()) {
cout << "Error opening video stream or file :(" << endl;
}
while (frame_counter<num_frames) {
Mat frame;
// Capture frame-by-frame
cap >> frame;
// If the frame is empty, break immediately
if (frame.empty())
break;
cvtColor(frame, frame, CV_BGR2GRAY);
for(int j=0;j<width_frame;j++) //we in above first extract a movie frame that as we know it is a image
//in this 'for' we extract that row data with a pointer to one of the row in th M_temp
M_temp.at<uchar>(frame_counter , j) = frame.ptr<uchar>(whichrow)[j];
frame_counter++;
}
// When everything done, release the video capture object
cap.release();
return M_temp;
}
int main() {
cap=VideoCapture("a valid path");
width_frame = cap.get(CV_CAP_PROP_FRAME_WIDTH);
heigth_frame = cap.get(CV_CAP_PROP_FRAME_HEIGHT);
num_frames = cap.get(CV_CAP_PROP_FRAME_COUNT);
Mat image= Mat::zeros(width_frame, num_frames, CV_8UC3);//initalize input
Mat image_o = Mat::zeros(width_frame, num_frames, CV_32FC3);//initialize output
for (int jj = 0;jj < heigth_frame;jj++) {
image = video_line_extractor(jj);
for (int j = 0;j < width_frame;j++)
temp_rec((float *)image.ptr<uchar>(j), (float *)image_o.ptr<uchar>(j), num_frames, 10);
}
imshow("Image", image);
waitKey(0);
return 0;
}

How can I get Opencv cv::Mat hsv pixels value?

I have a frame which is taken from video:
VideoCapture cap(videoPath);
Mat frame;
cap >> frame;
Frame have target which is blue. So I use Hsv:
Mat blue_hsv;
cvtColor(frame, blue_hsv, cv::COLOR_RGB2HSV);
inRange(blue_hsv, cv::Scalar(0, 50, 50), cv::Scalar(30, 255, 255), blue_hsv);
HSV İmage
Next, I want to get value of pixels. Is pixel white or black. But it didn't work:
for (int i = 0; i<blue_hsv.rows; i++)
{
for (int j = 0; j<blue_hsv.cols; j++)
{
Vec3b& hsv = blue_hsv.at<Vec3b>(i, j);
cout << hsv[0] << ",";
cout << hsv[1] << ",";
cout << hsv[2] << endl;
}
}
I take the "abord()" error. My main purpose is bringing the figure straight with using Pixels. So what can I do for it? How can reach value of hsv pixels?

Taking average of live webcam frames

I first used this code to capture webcam frames:
int main(int argc, char** argv)
{
VideoCapture cap(0); // open the default camera
if (!cap.isOpened()) // check if we succeeded
return -1;
cap.set(CV_CAP_PROP_FPS, 15);
std::vector<cv::Mat> images(100);
for (framenumb = 0; framenumb < 100; ++framenumb)
{
// this is optional, preallocation so there's no allocation
// during capture
images[framenumb].create(480, 640, CV_32FC3);
}
for (framenumb = 0; framenumb < 100; ++framenumb)
{
Mat frame;
cap >> frame;
if (frame.empty()) break; // end of video stream
imshow("webcam", frame);
if (waitKey(1) == 27) break; // stop capturing by pressing ESC
frame.copyTo(images[framenumb]);
}
and then tried to use the following code to average the captured frames:
Mat avgImg;
Mat capturedImg;
for (framenumb = 0; framenumb < 100; ++framenumb)
{
avgImg.create(480, 640, CV_32FC3);
capturedImg = images[framenumb];
cv::accumulate(capturedImg, avgImg);
}
avgImg = avgImg / 100;
avgImg.convertTo(avgImg, CV_8UC3);
imshow("averaged", avgImg);
But then it just broke the programme and gave me a black image. Can anyone help me to identify where the error is? Thank you very much
You need to:
Create a zero initialized accumulation image
Add every image to it
Divide the accumulated image by the number of images
You instead re-create an empty accumulation image at every frame.
The code should be changed as:
Mat avgImg(480, 640, CV_32FC3, Scalar()); // Create and zero initialize
Mat capturedImg;
for (framenumb = 0; framenumb < 100; ++framenumb)
{
// avgImg.create(480, 640, CV_32FC3); // Don't create each time!
capturedImg = images[framenumb];
cv::accumulate(capturedImg, avgImg);
}
You probably can simplify your code as:
Mat avgImg(480, 640, CV_32FC3, Scalar()); // Create and zero initialize
for (framenumb = 0; framenumb < 100; ++framenumb)
{
avgImg += images[framenumb];
}

Split image frame into 8*8 for DCT using OpenCV and C++

I need to pass fullPath into method FrameTo8by8(). In FrameTo8by8(), it will split the every frame into 8*8 blocks. (E.g. My video resolution is 1280*720 = 921,600. After that 921,600 / 64(8*8) = 14,400. So there will be total of 14,400 blocks of 8*8).
VideoSplitEngine.h
class VideoSplitEngine
{
public:
static VideoCapture capture;
static Mat fullimage;
//Default constructor
VideoSplitEngine();
//Declare a virtual destructor:
virtual ~VideoSplitEngine();
//Method
Mat Start();
void FrameTo8by8() const;
string GetFilePath() const;
private:
};
VideoSplitEngine.cpp
#include "StdAfx.h"
#include "VideoSplitEngine.h"
#include "UserInfo.h"
#include "Common.h"
VideoCapture VideoSplitEngine::capture;
Mat VideoSplitEngine::fullimage;
Mat VideoSplitEngine::Start()
string VideoSplitEngine::GetFilePath() const
{
cout<< endl;
cout << "Place video in Desktop and enter file name (e.g. vid.avi):" << endl;
cout<<"----------------------------------------------------------"<< endl;
//Get user desktop file path
string fullPath;
string userProfile = getenv("userprofile"); //GetEnvironmentVariable() is to get current userprofile (e.g."C:\Users\L30807")
string path = userProfile + "\\Desktop\\";
string vid;
getline (cin, vid); //Prompt to input file name
fullPath = path + vid;
capture.open(fullPath); //Read video
cout<< endl;
return fullPath;
}
Mat VideoSplitEngine::Start()
{
while(1)
{
bool bSuccess = capture.read(fullimage); // read a new frame from video
if (!bSuccess) //if not success, break loop
{
cout << "End of video" << endl;
destroyWindow("Original Video");
break;
}
imshow("Original Video", fullimage); //show the frame in "Original Video" window
if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop
{
cout << "esc key is pressed by user" << endl;
break;
}
}
return fullimage;
}
void VideoSplitEngine::FrameTo8by8() const
{
namedWindow("Original", CV_WINDOW_AUTOSIZE);
imshow("Original", fullimage);
int width = fullimage.size().width;
int height = fullimage.size().width;
cout << "Original image Width x Height is " << width << "x" << height << endl;
// Leave original alone, work on a copy
Mat dctImage = fullimage.clone();
// Step through the copied image with rectangles size 8x8
// For each block, split into planes, do dct, and merge back
// into the block. (This will affect the image from
// which the block is selected each time.)
for (int i = 0; i < height; i += 8)
{
for (int j = 0; j < width; j+= 8)
{
Mat block = dctImage(Rect(i, j, 8, 8));
vector<Mat> planes;
split(block, planes);
vector<Mat> outplanes(planes.size());
for (size_t k = 0; k < planes.size(); k++)
{
planes[k].convertTo(planes[k], CV_32FC1);
dct(planes[k], outplanes[k]);
outplanes[k].convertTo(outplanes[k], CV_8UC1);
}
merge(outplanes, block);
}
}
namedWindow("dctBlockImage");
imshow("dctBlockImage", dctImage);
waitKey(30);
}
I need help on how to split it or is there other methods to do it?
1.#berak is right.The prototype of function Rect() is Rect(x,y,width,height).So 'j' which refer to 'width' should be 'x'.(Actually I havn't found the prototype of Rect() from http://docs.opencv.org/2.4/index.html ,but cvRect() in the C API is cvRect(x,y,width,height).I think their prototypes maybe the same.)
2.for (int i = 0; i < height; i += 8) and for (int j = 0; j < width; j+= 8) will cause the error ""Unhandled exception at ...".By changing them to for (int i = 0; i < (height/8)*8; i += 8)andfor (int j = 0; j < (width/8)*8; j+= 8),this error will be sovled.
3.#user3743939 If you managed to sovle your problem,please post your solution to help others.
regards