简体   繁体   English

opencv图像窗口/ imshow

[英]opencv image window/imshow

I am just starting to use the Open CV library and one of my first code is a simple negative transform function. 我刚刚开始使用Open CV库,我的第一个代码之一就是一个简单的负变换函数。

#include <stdio.h>
#include <opencv2/opencv.hpp>

using namespace cv;
using namespace std;

void negative(Mat& input,Mat& output)
{
  int row = input.rows;
  int col = input.cols;
  int x,y;
  uchar *input_data=input.data;
  uchar *output_data= output.data;


  for( x=0;x<row;x++)
    for( y=0;y<col;y++)
      output_data[x*col+y]=255-input_data[x*col+y];

    cout<<x<<y;



}

int main( int argc, char** argv )
{
  Mat image;
  image = imread( argv[1], 1 );

  Mat output=image.clone();

  negative(image,output);

  namedWindow( "Display Image", CV_WINDOW_AUTOSIZE );
  imshow( "Display Image", output );

  waitKey(0);

  return 0;
}

I have added the extra line to check if the entire image is processed. 我添加了额外的行来检查是否处理了整个图像。 The problem i am facing with my output image is that negative transform is applied only to top half of the image. 我的输出图像面临的问题是负变换仅应用于图像的上半部分。

Now what happens is that the values for x and y are displayed only after i press a key (ie once the image is shown) 现在发生的是x和y的值仅在我按下一个键后显示(即一旦显示图像)

My question is why is the window being called before the function is executed ? 我的问题是为什么在执行函数之前调用窗口?

The fundamental problem in your code is that you are reading in a color image but you try to process it as grayscale. 您的代码中的基本问题是您正在阅读彩色图像,但您尝试将其作为灰度处理。 Therefore the indices shift and what really happens is that you only process the first third of the image (because of the 3-channel format). 因此,指数移动,实际发生的是你只处理图像的前三分之一(因为3通道格式)。

See opencv imread manual 请参阅opencv imread手册

flags – Specifies color type of the loaded image: flags - 指定加载图像的颜色类型:
>0 the loaded image is forced to be a 3-channel color image > 0加载的图像被强制为3通道彩色图像
=0 the loaded image is forced to be grayscale = 0加载的图像被强制为灰度

You've specified flags=1. 你已经指定了flags = 1。

Here's a way of doing it: 这是一种方法:

Vec3b v(255, 255, 255);
for(int i=0;i<input.rows;i++) //search for edges
{
    for (int j=0 ;j<input.cols;j++)
    {
        output.at<Vec3b>(i,j) = v - input.at<Vec3b>(i,j);
    }
}

Note that here Vec3b is a 3-channel pixel value as opposed to uchar which is a 1-channel value. 注意,这里Vec3b是3通道像素值,而uchar是1通道值。
For a more efficient implementation you can have a look at Mat.ptr<Vec3b>(i) . 为了更有效地实现,您可以查看Mat.ptr<Vec3b>(i)

EDIT: If you are processing lots of images, for a general iteration over the pixels the fastest way is: 编辑:如果您正在处理大量图像,对于像素的一般迭代,最快的方法是:

Vec3b v(255, 255, 255); // or maybe Scalar v(255,255,255) Im not sure
for(int i=0;i<input.rows;i++) //search for edges
{
    Vec3b *p=input.ptr<Vec3b>(i);
    Vec3b *q=output.ptr<Vec3b>(i);
    for (int j=0 ;j<input.cols;j++)
    {
        q[j] = v - p[j];
    }
}

See "The OpenCV Tutorials" -- "The efficient way" section. 请参阅“OpenCV教程” - “高效方式”部分。

Try to write: 试着写:

cout << x << y << endl;

The function is called before, but the output is not flushed directly, which results in your image appearing before the text is written. 之前调用该函数,但不直接刷新输出,这会导致图像在写入文本之前出现。 By adding an "endline", you force a flush. 通过添加“endline”,您可以强制刷新。 You could also use flush(cout); 你也可以使用flush(cout); instead of adding and endline. 而不是添加和结束。


For the negative, you can use the OpenCV function subtract() directly: 对于否定,您可以直接使用OpenCV函数subtract()

subtract(Scalar(255, 255, 255), input, output);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM