【问题标题】:Setting Pixel (i,j) in Color Image to Black in OpenCV C++在 OpenCV C++ 中将彩色图像中的像素 (i,j) 设置为黑色
【发布时间】:2015-10-07 01:34:50
【问题描述】:

我正在寻找分割彩色图像以尝试识别某些特征。如果像素不符合某些决策规则,我希望将其设置为黑色,否则我想让像素与第一次读取时完全相同。

我正在阅读图片:

Mat apples = imread("C:/Users.......", CV_LOAD_IMAGE_COLOR); 

到目前为止,我的尝试是将 i 行和 j 列中的像素设置为黑色:

apples.at<uchar>(i,j) = 0;

当循环遍历图像的所有行和列时,似乎跳过了图像的 2/3。

我也试过了:

Vec3b black;

black[0] = 0;
black[1] = 0;
black[2] = 0; 

apples.at<Vec3b>(i,j) = black;

这似乎几乎将图像过滤为。任何帮助,将不胜感激!

edit 我在图像矩阵上循环如下:

 for(int i=0;i<apples.rows;i++)
                {
                    for(int j=0;j<apples.cols;j++)
                        {
                            if(applescopy[0].at<uchar>(i,j) == 0 || applescopy[1].at<uchar>(i,j) == 0 || applescopy[2].at<uchar>(i,j) == 0 )
                              {
                                apples.at<Vec3b>(i,j) = black;
                              }
                        }
                }

如果我在第二个 for 末尾删除“if”语句并设置 apples.at uchar (i,j) = 0;无条件地,只有图像的左三分之一会变黑。

edit 2 我相信我在原始彩色图像上使用“分割”似乎修改了原始彩色图像。我已经复制了它以供循环使用,并且得到了更多预期的结果,谢谢大家!

【问题讨论】:

  • 请发布您所说的跳过图像 2/3 的代码,以便我们为您提供帮助。
  • .at(i,j) 确实访问 i,j uchar 值,如果您有 8 位灰度图像,则为 i,j 像素,但如果您有彩色图像使用 3 倍的“列”,因为 3 个 uchar 值是一个 RGB 值。最简单的方法是使用 .at(i,j) 如果您有 3 个通道,每个通道 8 位。

标签: c++ image opencv


【解决方案1】:

在特定条件为真后,将彩色图像中的像素值分配给白色。我已将其更改为白色,您可以通过将 255 替换为 0 将其设置为黑色。下面的代码将完成工作。

#include <opencv\cv.h>
#include<highgui\highgui.hpp>
#include <iostream>
using namespace std;
using namespace cv;
int main( ) {

Mat originalImage = imread("5.jpg", CV_LOAD_IMAGE_UNCHANGED); 

  if (originalImage.empty()){ 
    cout << "Error : Image cannot be loaded..!!" << endl;         
    return -1;
  } 

 for(int i=0;i<originalImage.rows;i++)
 {
  for(int j=0;j<originalImage.cols;j++)
  {
   if(originalImage.at<cv::Vec3b>(i,j)[0] == 0 || originalImage.at<cv::Vec3b>(i,j)[1] == 0 || originalImage.at<cv::Vec3b>(i,j)[2] == 0 )
    {
     //originalImage.at<Vec3b>(i,j) = 255;
     originalImage.at<cv::Vec3b>(i,j)[0]=255; // change it to white
     originalImage.at<cv::Vec3b>(i,j)[1]=255;
     originalImage.at<cv::Vec3b>(i,j)[2]=255;
        //   cout << i<<" " <<j<< endl; 
     }
   }
 }
 imwrite("result.png",originalImage);
namedWindow("MyWindow",CV_WINDOW_AUTOSIZE);
imshow("MyWindow", originalImage); 
waitKey(0);  
destroyWindow("MyWindow");
return 0;
 }

希望这是你需要的!!让我知道。

【讨论】:

    【解决方案2】:

    对于 3 通道 24 位图像,您可以通过 uchar 访问,但每列是单个通道值,因此您必须假设通道数的 3 倍!或者你只是使用 Vec3b 来访问任何地方的像素:

     for(int i=0;i<apples.rows;i++)
                {
                    for(int j=0;j<apples.cols;j++)
                        {
                         // read whole pixel value, which is a Vec3b for most color images. If you only read uchars you would have to multiply column index by 3 and add the channel number (0..2)
                         cv::Vec3b & pixel = applescopy[0].at<Vec3b>(i,j)
                         // decompose the pixel to three channels
                         uchar & B = pixel[0];
                         uchar & G = pixel[1];
                         uchar & R = pixel[2];
                         // test for any condition, e.g. if one of RGB is 0
                            if( anyCondition )
                              {
         //set whole Vec3b to some value
                                apples.at<Vec3b>(i,j) = black;
                              }
                        }
                }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-07-21
      • 2023-02-11
      • 1970-01-01
      • 2018-12-23
      • 1970-01-01
      • 2020-05-25
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多