Opencv--像素值变化后的图像显示

灰度图转为彩色图并不知道 RGB 与 灰度 的比例关系,只能简单地 设 一点的 R=G=B=灰度;

就算转成功了,看上去还是灰色。


<span style="font-size:18px;">if (img.type()==CV_8UC1) {
            
 //input image is grayscale
  
 cvtColor(img, cimg, CV_GRAY2RGB);
 } else {
            
 //input image is colour
 }</span>

在一个项目中,我调试一个改变像素的图像的程序,发现:当格式是jpg的时候不一定能更新,也就是说三通道确实是改变了,但图像却不会改变。身为菜鸟的我也不知道原因为什么jpg有时候不能显示,但根据调试,格式为bmp的是可以实现的。格式为bmp的是可以实现的。格式为bmp的是可以实现的。重要的事情说3遍!!!

另外一个牢记的知识点:在使用cvGet2D函数获得操作目标并运行后,一定要使用cvSet2D来设置RGB。


简单介绍一下cvGet2D

cvget2d函数:返回特殊的数组元素;
CvScalar cvGet2D( const CvArr* arr, int idx0, int idx1 );
arr:输入数组.
idx0:元素下标第一个以0为基准的成员;
idx1:元素下标第二个以0为基准的成员;
idx2:元素下标第三个以0为基准的成员;
idx:元素下标数组
函数cvGet*D 返回指定的数组元素。对于稀疏数组如果需要的节点不存在函数返回0 (不会创建新的节点)
同样,用cvSet2D即可设置图片的RGB值。
参考实例如下: 

CvScalar s;
for(y = 0; y < img->height; y++) {
for(x = 0; x < img->width; x++) {
s = cvGet2D(img, y, x);
}
}

贴上代码:

#include <stdio.h>
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;

int main()
{
	IplImage* pFrame = NULL;
    IplImage* pFrImg = NULL;
	cvNamedWindow("三通道操作",1);
	IplImage* image=cvLoadImage("board.bmp",0);//按照图片本身的格式操作
	//cvShowImage("图像显示",image);
    for (int i = 0; i <image->height; i++)  
   {  
      for (int j = 0; j <image->width; j++)  
	  {           
		  //间接访问
        CvScalar s=cvGet2D(image,i,j); //其中i代表y轴(第i行),即height;j代表x轴(第j列),即width。    
         //if((s.val[1]<150)||(s.val[1]>170))
		   //s.val[1]=0;
		s.val[0]=123;s.val[1]=123;s.val[2]=123;
		cout<<"B="<<s.val[0]<<setw(5)<<"G="<<s.val[1]<<setw(5)<<"R="<<s.val[2]<<endl;  
      }  
    }  
	cvShowImage("图像显示",image);
	cvWaitKey(0);
	cvReleaseImage(&image);
	cvDestroyWindow("图像显示");
	return 0;
}

看看结果:


当然这是作为 IPlImage形式来做的。现在都已经用Mat矩阵操作量了。至于为什么是灰度图,三个通道相等。改变通道后会直接在图像中改变,不需要更新函数。

贴上操作后代码:

#include <stdio.h>
#include <cv.h>
#include <highgui.h>
using namespace std;
using namespace cv;

int main()
{
	IplImage* pFrame = NULL;
    IplImage* pFrImg = NULL;
	cvNamedWindow("三通道操作",1);
	IplImage* image=cvLoadImage("board.bmp",1);//按照图片本身的格式操作,0是强制灰度图
	//cvShowImage("图像显示",image);
    for (int i = 0; i <image->height; i++)  
   {  
      for (int j = 0; j <image->width; j++)  
	  {           
		  //间接访问,设置图片RGB
        CvScalar s=cvGet2D(image,i,j); //其中i代表height;j代表width。    
        if((s.val[0]<150)||(s.val[0]>170))
		   s.val[0]=0;
		//s.val[0]=123;s.val[1]=123;s.val[2]=123;
		cout<<"B="<<s.val[0]<<setw(5)<<"G="<<s.val[1]<<setw(5)<<"R="<<s.val[2]<<endl;
		cvSet2D(image,i,j,s);
      }  
    } 
	//cvSaveImage("图像显示",image);
	cvShowImage("图像显示",image);
	cvWaitKey(0);
	cvReleaseImage(&image);
	cvDestroyWindow("图像显示");
	return 0;
}



  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV中,当对二值图像进行旋转时,边缘像素值可能会发生变化。这是由于旋转操作会导致像素位置的改变,因此原来的边缘像素可能会被移动到其他位置。 在旋转过程中,OpenCV会使用插值算法来计算新位置的像素值。默认情况下,OpenCV使用双线性插值算法来估计新位置的像素值,这可能会导致边缘像素值的微小变化。 如果你希望在旋转后保持二值图像的边缘像素值不变,你可以考虑使用最近邻插值算法。最近邻插值算法会简单地选择最接近目标位置的像素值作为新位置的像素值,不进行其他的插值计算。 以下是一个示例代码,展示了如何使用最近邻插值算法来旋转二值图像并保持边缘像素值不变: ```python import cv2 import numpy as np # 读取二值图像 image = cv2.imread('binary_image.png', cv2.IMREAD_GRAYSCALE) # 找到二值图像的边缘 contours, _ = cv2.findContours(image, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) # 计算包围边缘的最小矩形框 rect = cv2.minAreaRect(contours[0]) # 获取旋转角度和矩形框的中心点 angle = rect[2] center = rect[0] # 旋转角度(以逆时针方向为正) rotated = cv2.warpAffine(image, cv2.getRotationMatrix2D(center, angle, 1.0), (image.shape[1], image.shape[0]), flags=cv2.INTER_NEAREST) # 显示原始和旋转后的图像 cv2.imshow('Original Image', image) cv2.imshow('Rotated Image', rotated) cv2.waitKey(0) cv2.destroyAllWindows() ``` 在上面的示例中,我们使用`cv2.warpAffine`函数来执行旋转操作,并将插值标志设置为`cv2.INTER_NEAREST`,以使用最近邻插值算法。 请注意,使用最近邻插值算法可能会导致旋转后的图像边缘变得锐利,而不是平滑。这是因为最近邻插值算法只选择最接近的像素值,而不考虑其他像素的加权平均。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值