I'm trying to print out individual values from the matrices from all images. However, the output that i am receiving are weird symbols and alphabets.
I have 60 images and each of them have a matrix of 320x240.
Sorry, my code may not be good or up to standard as i'm not very good in this.
Thanks :)
vector<Mat> images;
for (int i = 0;i < 60;i++) {
if (i < 10) {
Mat in = imread("ts_04-11-21_16-27-0" + to_string(i) + "-mod.jpg", CV_8UC1);
images.push_back(in);
}
else {
Mat in = imread("ts_04-11-21_16-27-" + to_string(i) + "-mod.jpg", CV_8UC1);
images.push_back(in);
}
}
for (int i = 0; i < 60; i++) {
for (int j = 0; j < 320; j++) {
for (int k = 0; k < 240; k++) {
cout << images[i].at<uint8_t>(j, k) << endl;
}
}
}
Related
I have a problem. I found an academic paper for age detection, which tries to predict the age given an image with a face. I've done almost all steps. However, it feels that face normalization doesn't work for me. I searched how to do it, and I don't know why it doesn't look how it should look like.
I don't know what it's missing, some help would be appreciated.
This is my code:
void normalize_face(Mat img) {
int height = img.rows;
int width = img.cols;
int no_px = height * width;
int hist[256] = { 0 };
int min_value = 255;
int max_value = 0;
Mat dst = img.clone();
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
uchar px = img.at<uchar>(i, j); // CV_8UC3 image type, with all channels equal -> grayscale
hist[px]++;
}
}
for (int i = 0; i < 256; i++) {
if (hist[i] != 0 && i < min_value)
min_value = i;
if (hist[i] != 0 && i > max_value)
max_value = i;
}
float constant_factor = 255.0f / (max_value - min_value);
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
uchar px = img.at<uchar>(i, j);
float new_px_value = constant_factor * img.at<uchar>(i, j);
dst.at<uchar>(i, j) = (int)new_px_value;
}
}
std::cout << "Minim: " << min_value << ", maxim: " << max_value << "\n";
std::cout << "Constant factor:" << constant_factor<<"\n";
imshow("normalized face", dst);
imshow("normal face", img);
waitKey(0);
}
This is what I get:
And this is what I should get:
I've looked at similar questions (such as this, this, and this), but I still can't figure this out. On a few test cases, I'm getting the error and can't make sense of it. The error I'm getting is:
free(): invalid next size (fast)
My code uses the Robot Coin Collection algorithm. My implementation of it is below:
int collectTens( vector< vector<int> > grid ) {
vector<vector<int>> result(grid.size(), vector<int>(grid.size(), 0));
int rows = grid.size();
int cols = grid[0].size();
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (grid[i][j] % 10 != 0) {
grid[i][j] = 0;
}
}
}
result[0][0] = grid[0][0];
for (int k = 1; k < cols; k++) {
result[0][k] = result[0][k - 1] + grid[0][k];
}
for (int i = 1; i < rows; i++) {
result[i][0] = result[i - 1][0] + grid[i][0];
for (int j = 1; j < cols; j++) {
result[i][j] = max(result[i - 1][j], result[i][j - 1]) + grid[i][j];
}
}
cerr << result[rows - 1][cols - 1] << endl;
return result[rows - 1][cols - 1];
}
In the test cases that the error occurs, the result can be outputted using stderr but will not be able to return anything due to the error. Which is the part that doesn't really make sense to me, because it is the same position in the 2D vector.
The line
vector<vector<int>> result(grid.size(), vector<int>(grid.size(), 0));
creates square grid, not a rectangular grid. You probably meant to use:
vector<vector<int>> result(grid.size(), vector<int>(grid[0].size(), 0));
^^^^
I suggest using:
int rows = grid.size();
int cols = grid[0].size();
vector<vector<int>> result(rows, vector<int>(cols, 0));
If we access pixel by a pointer using step and data of Mat Image. see example below
int step = srcimg.step;
for (int j = 0; j < srcimg.rows; j++) {
for (int i = 0; i < srcimg.cols; i++) {
//this is pointer to the pixel value.
uchar* ptr = srcimg.data + step* j + i;
}
}
Question:
How can we perform 3x3 weighted avg operations with image step by a pointer?
thanks
You mustn't use data field in opencv because memory is not allways continuous. you can check this using isContinuous() method.
Now you can do like this (image type is CV_8UC1)
for (int i = 1; i < srcimg.rows-1; i++)
{
for (int j = 1; j < srcimg.cols-1; j++)
{
int x=0;
for (int k=-1;k<=1;k++)
{
uchar* ptr=srcimg.ptr(k+i)+j-1;
for (int l=-1;l<=1;l++,ptr++)
x +=*ptr;
}
}
}
image border are not processed. Now if you want to blur an image use blur method
You can use this post too
I am doing something like this .
int sr = 3;
for (int j = 0; j < srcimg.rows; j++) {
for (int i = 0; i < srcimg.cols; i++) {
uchar* cp_imptr = im.data;
uchar* tptr = im.data + imstep *(sr + j) + (sr + i);
int val_tptr = cp_imptr [imstep *(sr + j) + (sr + i)]; //pointer of image data amd step at 3x3
int val_cp_imptr = cp_imptr[imstep *j + i];
double s = 0;
for (int n = templeteWindowSize; n--;)
{
for (int m = templeteWindowSize; m--;)
{
uchar* t = tptr; //pointer of template
// sum
s += *t;
t++;
}
t += cstep;
}
}
cout << endl;
}
I am using cv::ximgproc::SuperpixelSLIC opencv c++ to generate segments of image. I want each segment label to be unique. Here is my code.
Mat segmentImage() {
int num_iterations = 4;
int prior = 2;
bool double_step = false;
int num_levels = 10;
int num_histogram_bins = 5;
int width, height;
width = h1.size().width;
height = h1.size().height;
seeds = createSuperpixelSLIC(h1);
Mat mask;
seeds->iterate(num_iterations);
Mat labels;
seeds->getLabels(labels);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
if (labels.at<int>(i, j) == 0)
cout << i << " " << j << " " << labels.at<int>(i, j) << endl;
}
}
ofstream myfile;
myfile.open("label.txt");
myfile << labels;
myfile.close();
seeds->getLabelContourMask(mask, false);
h1.setTo(Scalar(0, 0, 255), mask);
imshow("result", h1);
imwrite("result.png", h1);
return labels;
}
In label.txt file I observe that label 0 has been given to two segments (i.e. segment include pixel(0,0) and pixel(692,442). These two segments are pretty far away.
Is this normal thing or my code is incorrect. Please help me to find unique label for each segment.
What you essentially need is a connected components algorithm. Without knowing the exact SLIC implementation you use, SLIC usually tends to produce disconnected superpixels, i.e. disconnected segments with the same label. A simple solution I used is the connected components algorithm form here: https://github.com/davidstutz/matlab-multi-label-connected-components (originally from here: http://xenia.media.mit.edu/~rahimi/connected/). Note that this repository contains a MatLab wrapper. In your case you only need connected_components.h together with the following code:
#include "connected_components.h"
// ...
void relabelSuperpixels(cv::Mat &labels) {
int max_label = 0;
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
if (labels.at<int>(i, j) > max_label) {
max_label = labels.at<int>(i, j);
}
}
}
int current_label = 0;
std::vector<int> label_correspondence(max_label + 1, -1);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
int label = labels.at<int>(i, j);
if (label_correspondence[label] < 0) {
label_correspondence[label] = current_label++;
}
labels.at<int>(i, j) = label_correspondence[label];
}
}
}
int relabelConnectedSuperpixels(cv::Mat &labels) {
relabelSuperpixels(labels);
int max = 0;
for (int i = 0; i < labels.rows; ++i) {
for (int j = 0; j < labels.cols; ++j) {
if (labels.at<int>(i, j) > max) {
max = labels.at<int>(i, j);
}
}
}
ConnectedComponents cc(2*max);
cv::Mat components(labels.rows, labels.cols, CV_32SC1, cv::Scalar(0));
int component_count = cc.connected<int, int, std::equal_to<int>, bool>((int*) labels.data, (int*) components.data, labels.cols,
labels.rows, std::equal_to<int>(), false);
for (int i = 0; i < labels.rows; i++) {
for (int j = 0; j < labels.cols; j++) {
labels.at<int>(i, j) = components.at<int>(i, j);
}
}
// component_count would be the NEXT label index, max is the current highest!
return component_count - max - 1;
}
On the obtained labels, run relabelConnectedSuperpixels.
I am new in SFML and working on game "Memory Match" 4x4. To simplify I am loading 2 different image.Each time I get the last image on array.Can anyone say me what I am doing wrong with this?
string s[] = {
"C:/Users/Eldar/Desktop/sfml/image.png",
"C:/Users/Eldar/Desktop/sfml/redDie.png"
};
int k = 0;
for (int i = 0; i <= 3; i++){
for (int j = 0; j <= 3; j++){
cout << k << endl;
Cards[i][j].setScale(1, 1);
Cards[i][j].setPosition(0 + ioffset, 0 + joffset);
textureCard.loadFromFile(s[k]);
Cards[i][j].setTexture(textureCard);
k++;
if (k == 2) k = 0;
}
}